Push is not a function

Push is not a function
0

#1
function bindCheckbox() {
		let inputCheckbox = document.querySelectorAll('input[type=checkbox]');
		let favoriteList = document.getElementById('favorites');

			inputCheckbox.forEach(function(element, index) {
				inputCheckbox[index].addEventListener('change', function() {
					let fav = localStorage.getItem('favoList') || [];
					console.log(fav);
					let joke = this;
					if(joke.checked && joke.parentNode.parentNode.id === 'list-of-jokes') { 
					   addFavorite(joke.id, joke.parentNode.innerText, fav);
					} 
				});
		}
	}


	function addFavorite(idNum, jokeText, fav) {
		let norrisJoke = [{
			id: idNum,
			joke: jokeText
		}];
		console.log(fav);
		let favorites = fav;

		console.log(idNum, jokeText);
		console.log(norrisJoke);
		favorites.push(norrisJoke);
		localStorage.setItem('favoList', JSON.stringify(norrisJoke));
	}

the value should be pushed into fav element, but that is kind of inside a closure. So the value should be pushed inside an innerfunction and stored inside an element inside the outer function. The localstorage outputs [object object] and no value of norrisjoke.

https://codepen.io/chichichi/pen/JMqvyP?editors=1111


localStorage [object object]
#2

Where is the code where you output norrisjoke? I do not see it here. Can you provide a link to your entire project? It would make it easier to help you.


#3

Check the added codepen


#4

I looked at your code and tested it out. I am not seeing the problem you describe. Can you tell me which line number you are trying to display the localStorage which results in the [object object]?


#5

let fav = localStorage.getItem(‘favoList’) || []; inside bindCheckbox() function


#6

Got it. I will review and let you know what I find.


#7

The problem starts in the bindCheckbox function. The following line calls addFavorite, but the variable fav is an object and not an array. So, when you try to use the push function on fav in your addFavorite function, you get that error message, because fav must be an array to use push.

addFavorite(joke.id, joke.parentNode.innerText, fav);

#8

Oke I get it now. How could I solve this correctly.


#9

I figured it out and there are two issues.

#1) In the following line, you attempt to set fav to the value stored in localStorage’s ‘favoList’. When you use getItem, you should use JSON.parse around it, because if not, the value returned is just a string. The JSON.parse will convert it to an object/array.

let fav = localStorage.getItem('favoList') || [];

Wrap it like:

let fav = JSON.parse(localStorage.getItem('favoList')) || [];

#2) The following is your addFavorite function:

	function addFavorite(idNum, jokeText, fav) {
		let norrisJoke = {
			id: idNum,
			joke: jokeText
		};
		console.log(fav);
		let favorites = fav;

		console.log(idNum, jokeText);
		console.log(norrisJoke);
		favorites.push(norrisJoke);
		localStorage.setItem('favoList', JSON.stringify(norrisJoke));
	}

The first time you load the page (assuming localStorage is empty), the function works correctly, because favorites is a blank array. The second time it does not, because of what you set ‘favoList’ to in localStorage. You set ‘favoList’ to norrisJoke. What kind of value is norrisJoke?


#10

To add a little to Randell’s excellent answer…

Just as a general debugging concept, whenever you see “[blank] is not a function of …”, that is javascript telling you that whatever prototype method you are trying to use is not a prototype of that variable type. In this case, push is a method defined for arrays, not objects. You would get the error if you tried to apply it to a string. Whenever I get that error, the first thing I do is check to see I have the right method and then I check the typeof of that variable. Usually I’ve made a mistake and the variable isn’t the type I thought it was.


#11

Oke that is a good one, will use that often.


#12

Thanks for your feedback.


#13

It outputs the json values when it has been clicked on.


#14

Did you make the changes I mentioned?


#15

Ye, but I think you should not use codepen for this, cuz it would not store in localstorage…


#16

It works fine in Codepen when I made the changes I suggested. Just keep in mind that unless you clear out the localStorage on page load, you will already have items in localStorage from a previous visit to the project. That would be the same if you ran it locally or on Codepen.


#17

When I click on a checkbox it will pass an id and text, but looking at the localStorage I see [object object]. I know the typeof storage is object and should be an array. The question from my side is, how should I turn an object into an array?

	function addFavorite(jokeId, jokeText) {
		let storage = localStorage.getItem('favoList') || [];
		let norrisJoke = {
			id: jokeId,
			joke: jokeText
		};
		console.log(norrisJoke);
		storage.push(norrisJoke);
		console.log(typeof storage);
		localStorage.setItem('favoLis', norrisJoke);
    }

#18

You need to review the information I gave you in your other thread related to using .getItem.

See the other thread here.


#19

The data in localstorage must be in a string format so when you are calling setItem you need to stringify it.

localStorage.setItem('thedata', JSON.stringify(your_object));

And when you retrieve the data from local storage you have to parse it back to an object.

 localStorage.getItem(JSON.parse('thedata')) ;

#20

typeof favorites is still an object… —> let fav = JSON.parse(localStorage.getItem(‘favoList’))|| [];