Good afternoon,
Please, could you help me with an issue below.
I am getting an error "Cannot read properties of null (reading 'split')" when trying to click "cancel" on prompt.
What all I want, to loop canceled when I cancel it in prompt.
ps.: this is a simple array with a name/surname which in future will shows via console.log
function UserList () {
let users = [];
while(true) {
users.push (prompt('Please, enter your name surname?').split(' '));
if (prompt=== null) {
alert('cancel');
}
}
}
let userList = new UserList();
You need to test whether the result of prompt() is null before you try to split it.
You need to break out of the loop when the user cancels, otherwise the function will never return.
Also, since you're using this as a object constructor, users should be a property this.users.
function UserList () {
this.users = [];
while(true) {
let response = prompt('Please, enter your name surname?');
if (response == null) {
alert('cancel');
break;
}
this.users.push (response.split(' '));
}
}
Related
I'm trying to make movies likeable one time by storing them in an array like this:
let likedMovies = [];
const movieLike = document.getElementById("likeButton");
likedMovies = JSON.parse(localStorage.getItem("likedMovies"));
movieLike.addEventListener("click", () => {
if (likedMovies.indexOf(allMovies[i].name) === -1) {
confirm("Movie liked");
axios.patch(`url`);
likedMovies.push(allMovies[i].name);
localStorage.setItem("likedMovies", JSON.stringify(likedMovies));
return true;
}
confirm("Movie already liked");
return false;
});
it was working this afternoon but now the console display an error log saying this: "script.js:75 Uncaught TypeError: Cannot read properties of null (reading 'indexOf')
at HTMLDivElement." and when I log my likedMovies array, it says that arrays's "null", could you please help me understanding why it doesn't work ?
The problem is that you are reassigning likedMovies with the result of JSON.parse which is null if it's unable to parse it.
let likedMovies = JSON.parse(localStorage.getItem("likedMovies")) || [];
This should solve the error, but also you can do some optimization by storing it as an Object.
let likedMovies = JSON.parse(localStorage.getItem("likedMovies")) || {};
const movieLike = document.getElementById("likeButton");
movieLike.addEventListener("click", () => {
if (likedMovies[allMovies[i].name]) {
confirm("Movie liked");
axios.patch(`url`);
likedMovies[allMovies[i].name] = true;
localStorage.setItem("likedMovies", JSON.stringify(likedMovies));
return true;
}
confirm("Movie already liked");
return false;
});
Now your search will happen not in linear time which is O(n) but in constant O(1). Tiny performance improvement.
I'm trying to make an app that will help me with my workouts and help me constantly lift more so that I can get stronger. I keep getting the error "Cannot set inner property of null" on the very bottom when I try to output the variables to the HTML. It's the code under the last section of comments that I am getting the error. Can some give me some guidance on how to fix this?
//Get the variables from the user. This will be the previous exercise or the exercise that the user has performed
const userSet = document.getElementById("set-user-1");
const userReps = document.getElementById("reps-user-1");
const userWeight = document.getElementById("weight-user-1");
var futureSet;
var futureReps;
var futureWeight;
//Define the functions that need to be done between the previous exercise and the next exercise
function getNewSet(previousSet) {
return previousSet;
}
function getNewRep(previousReps){
if(previousReps < 12) {
return previousReps + 2;
} else {
previousReps = 6;
return previousReps;
}
}
function getNewWeight(previousReps, previousWeight) {
if(previousReps < 12){
return previousWeight;
} else {
previousWeight = previousWeight + 10;
return previousWeight;
}
}
//Make a function that runs all the functions with the user input
function getNewWorkout() {
futureSet = getNewSet(parseInt(userSet));
futureReps = getNewRep(parseInt(userReps));
futureWeight = getNewWeight(parseInt(userReps, userWeight));
return futureSet;
return futureReps;
return futureWeight;
}
//Output will go to the future exercise dividers
document.getElementById("future-sets").innerHTML = futureSet;
document.getElementById("future-reps").innerHTML = futureReps;
document.getElementById("future-weight").innerHTML = futureWeight;
The error is in the last two lines of this function. A function can only return one value, it might be worth putting all the values in an array
and then returning it.
//Make a function that runs all the functions with the user input
function getNewWorkout() {
futureSet = getNewSet(parseInt(userSet));
futureReps = getNewRep(parseInt(userReps));
futureWeight = getNewWeight(parseInt(userReps, userWeight));
return futureSet;
//error here
return futureReps;
return futureWeight;
}
So you can update your code as follows to return object,
function getNewWorkout() {
const futureSet = getNewSet(parseInt(userSet));
const futureReps = getNewRep(parseInt(userReps));
const futureWeight = getNewWeight(parseInt(userReps, userWeight));
return {futureSet, futureReps, futureWeight};
}
Which you can access through object.
This kind of error comes when you load the script before DOM is ready. You can try to load the script at the end of the HTML, usually in footer. This should fix your error.
Also, please call the function 'getNewWorkout()' in your script to get expected output.
I get the error in the title even though I have tried all the solutions. About the value of null;
If my code is ;
Output: TypeError: Cannot read property of null
case '!facebook':
face.Profile(facebook, function(result) {
let like = result.profiles.like;
let comments = result.profiles.comments;
if(like === null || comments === null){
//code.
}
else {
//code.
}
});
break;
You have to verify that each child of your object exists before you reference the next level. In your case, that means testing the existence of result and then result.profiles before trying to use any of the object values in profiles. See the code below.
Without seeing the rest of your case statement or how you're setting the value of face, it's hard to tell if you're going to run into other issues.
case '!facebook':
face.Profile(facebook, function(result) {
// Set default values
let like = null;
let comments = null;
// Set values only if there's a result containing profiles
if (result && result.profiles) {
like = result.profiles.like;
comments = result.profiles.comments;
}
if (like === null || comments === null){
//code
} else {
//code
}
});
break;
I am pulling data from woocommerce.
Which I have defined as so in my render():
const product2 = this.state.products2;
Now I want to target a particular value in this returned object as such:
const defaultLace = product2.default_attributes[0].option
However, the above renders a Type Error but const defaultLace = product.default_attributes; does not render an error and in the console I can see the data similar in this way;
default_attributes: [
{
id: 0,
name: "Lace",
option: "Closure"
}
]
What is happening here that this const defaultLace = product2.default_attributes[0].option renders an error?
Any help?
---EDIT----
broken code replication: XXXX
products2 is initially an empty array before the request has finished, so accessing products2.default_attributes will give undefined, and trying to access [0] on that will give rise to your error.
You could wait with the rendering until the products2 array has been filled with data.
Example
render() {
const product2 = this.state.products2;
if (product2.length === 0) {
return null;
}
const productSize = product2[0].default_attributes[0].option;
return (
<div>
<h1>{productSize}</h1>
</div>
);
}
This code is OK.
But when you retrive data from remote server you must check that data exist and are in your structure.
When you use
const defaultLace = product2.default_attributes[0].option
you must check data as:
if(product2 && product2.default_attributes && Array.isArray(product2.default_attributes) && product2.default_attributes.length > 0) {
const defaultLace = product2.default_attributes[0].option
} else {
throw new Error('Bad data');
}
I am writing a function which searches for a value in my IndexedDB and if it finds one, then it should return 1, else it should return 0. The problem is that it always returns 0 though the value exists in a database (variable arr is incremented, but 0 is returned as a result). The code is as follows:
searchAllValues: function(store, type)
{
var arr = 0;
AAA.initDb(function()
{
var obj = {};
AAA.aaaDb.transaction(store).objectStore(store).openCursor().onsuccess = function(store)
{
var storeresult = store.target.result;
if(storeresult.value.value == type ){
arr++;
}else{console.log('value NOT found');}
storeresult ? (obj[storeresult.key] = storeresult.value.value, storeresult["continue"]()) : callback(obj)
}
});if(arr!=0){return 1}else{return 0}
}
EDIT_1:
Ok, I have refactored the code as follows:
addInfo: function(store, type, info)
{
var arr = [];
P4S.p4sPushDb.transaction(store).objectStore(store).openCursor().onsuccess = function(store)
{
var storeresult = store.target.result;
console.log('value of storeresult==>'+storeresult.value.value);
if(storeresult.value.value == info)
{
arr.push(storeresult.value.values);return;//If it finds something it should stop here, no more search or anything to be done
}else
{
console.log('continuing..');
storeresult['continue']();
}
console.log('arr length==> '+arr.length);//If it finds nothing after the looping the whole DB, I want it to print this statement, only once (to send it to my DB actually but sending code is omitted for simplicity).
}
}
Instead I get console.log('arr length==>') statement executed 2 times, for every key in my object store (there are 2 of them actually). So it is doing the code when it finds nothing AND when it finds the value in the DB. Any ideas how to fix it?
Any ideas would be welcome, Thank You
Because by the time the line if(arr!=0){return 1}else{return 0} is executed the db transaction is not complete and value of arr is 0. Though never used indexedDb, but webSql do take some extra miliseconds to read from DB.
Try to put your return logic inside the onsuccess function where you incrementing the arr. You can simply test it by printing value of arr just before your return logic
You need to learn about how to write asynchronous javascript. There are several other indexedDB questions where there are explanations as to why this happens.
For example: Uncaught TypeError: Cannot read property 'transaction' of null with an indexeddb
function addInfo(store, type, info, next)
{
var arr = [];
P4S.p4sPushDb.transaction(store).objectStore(store).openCursor().onsuccess = function(store)
{
var storeresult = store.target.result;
console.log('value of storeresult==>'+storeresult.value.value);
if(storeresult.value.value == info)
{
arr.push(storeresult.value.values);
next(arr);//If it finds something it should stop here, no more search or anything to be done
}else
{
console.log('continuing..');
storeresult.continue();
}
console.log('arr length==> '+arr.length);//If it finds nothing after the looping the whole DB, I want it to print this statement, only once (to send it to my DB actually but sending code is omitted for simplicity).
}
}
Added an extra parameter called 'next' to your the addInfo function.
'next' param is the very last function called if the condition (storeresult.value.value == info) is true.
The next function which you create, will use the 'arr' variable and do whatever with it
your 'return statement' doesnt work the sameway with asynchronous functions, would highly advice you search up asynchronous functions to get a gist of how its different to regular functions
This is how you would call your newly edited function:
addInfo(store,type,info,function(arr){
//do something with arr
})
Note that you have a potential state which would break your code
what if the cursor reaches the end of its iterations and never meets that condition (storeresult.value.value == info). storeresult would be null, and the check for the condition (null.value.value == info) will throw an exception
correction:
function addInfo(store, type, info, next)
{
var arr = [];
P4S.p4sPushDb.transaction(store).objectStore(store).openCursor().onsuccess = function(store){
var storeresult = store.target.result;
if(storeresult){
if(storeresult.value.value == info){
arr.push(storeresult.value.values);
next(arr);
}else storeresult.continue();
}else next();
}
}
And when you call it you handle the scenario whereby arr == null
addInfo(store,type,info,function(arr){
if(arr){
//do something with arr
}else{
//do somethingelse when arr == null
}
})