I have an object, called user, which may or may not have subproperties defined. For example, sometimes there is no "pages" object, sometimes you can go user.pages.someothervariable.
I can see in EJS how to check that user exists, but how can I check that user.pages.someothervariable exists without getting a "cannot access property of undefined" error.
I've tried this and typeof, but cannot get it to work.
<% if(locals.user.pages.pageVisits){ %>foo defined<% }else{ %>foo undefined<% } %>
I get this error:
Cannot read property 'pageVisits' of undefined
You can use short-circuiting && --
if(locals.user.pages && locals.user.pages.pageVisits) { /* do sth */ }
If user.pages is falsy, the evaluation won't proceed.
If the chain gets too long, you can try to encapsulate it into a function, like --
function getPage(user) {
return (user && user.pages && user.pages.accountPage)
|| "0"; // a fallback if the left side is falsy
}
You can check if your user has a pages field by running if(local.user.pages). This is because almost any value can be evaluated in if statements in JS. If user.pages is null, then the if statement will return false. If user.pages exists it will return true.
You could do a try-catch to avoid messiness:
var obj = {
test: "hello"
}
try {
console.log(obj.fakeKey.otherFakeKey)
}
catch(ex) {
console.log("Caught")
}
Related
I spotted that when I'm using while loop, cypress does not work, so instead of while loop I found this kind of solution:
const functionName = () => {
if ( a != b ) {
this.functionName();
} else {
cy.get(".selector").click()
}
};
This block of code (typescript) works really well, but 'this' is highlighted in red and the message appears: "Object is possibly 'undefined'."
Any idea how can I to get rid off this error?
Assuming it's a typescript error, add the Non-null assertion operator
// Compiled with --strictNullChecks
function validateEntity(e?: Entity) {
// Throw exception if e is null or invalid entity
}
function processEntity(e?: Entity) {
validateEntity(e);
let s = e!.name; // Assert that e is non-null and access name
}
For reference, How to suppress "error TS2533: Object is possibly 'null' or 'undefined'" answers the same question.
You probably don't need the this. prefix at all, since the function is defined on the current scope (not a class method).
When users are not logged into my website, the state of user is set to null.
However, this throws up a lot of issues on some pages where i look to see if this.$store.user
For example, if I were to have a simple check such as
if (this.$store.getters.userInfo.likedProjects.includes(title)) {this.hasLiked = true}
and the user is not logged in (thus, setting the state of user to null by default) I get this error;
_this.$store.getters.userInfo is null
How should I correctly handle this sort of issues so that my console does not get flooded with typescript errors?
My initial idea was to first check if user.loggedIn == true and wrap everything inside of that, but that seems awfully messy just to avoid some errors...
Use optional chaining, which is available in TypeScript 3.7+:
if (this.$store.getters.userInfo?.likedProjects.includes(title)) {
this.hasLiked = true;
}
If userInfo is null or undefined, then the entire statement this.$store.getters.userInfo?.likedProjects.includes(title) will return undefined instead of throwing an error.
If likedProjects may also be null or undefined, then you need to use optional chaining on that property too, i.e.:
if (this.$store.getters.userInfo?.likedProjects?.includes(title)) {
this.hasLiked = true;
}
if(this.$store.getters.userInfo){
if (this.$store.getters.userInfo.likedProjects.includes(title)) {this.hasLiked = true}
}
In my application, I want to check if a token exists for the user and, based on this, redirect them somewhere. I have defined the code as follows:
componentDidMount() {
SecureStore.getItemAsync('token').then((val) => {
val ? Actions.link() : null
}
).then(this.setState({ loaded: true }))
}
However, Actions.link() is never called even though the value does exist and can be logged to the console.
How does one correctly check whether a variable exists or not?
I think it might have something to do with the short if/else
can you try:
if (val) {
Actions.link()
}
I get an error if part of the Amazon product is missing. For example, I can do this check:
typeof success.data[i].OfferSummary[0].LowestNewPrice[0].Amount !== "undefined"
but if OfferSummary is not defined this would throw an error. Do I need to check every object under the data? Is there an easier way?
I was thinking of doing a try ... catch and trapping the error, but I'm sure someone has run into this before.
Yes you'll need to check at each step or wrap the check in a try catch block.
At the moment you're trying to access a property on undefined, which does not exist.
if (success.data[i] && success.data[i].OfferSummary[0] &&
success.data[i].OfferSummary[0].LowestNewPrice[0] &&
success.data[i].OfferSummary[0].LowestNewPrice[0].Amount !== undefined) {}
//OR
var amount = null;
try {
amount = success.data[i].OfferSummary[0].LowestNewPrice[0].Amount;
} catch( err ) {}
if (amount !== undefined){}
If you're using lodash you may use function _.get:
var amount = _.get(success, 'data[' + i + '].OfferSummary[0].LowestNewPrice[0].Amount', 0);
The 3rd parameter is default value which will be returned in case of smth in this path is not defined.
Actually, under the hood it's just a set of if-checks but the code looks more elegant.
I have a page which works on my localhost.. when I put t on a remote server, it gave an error. the code which returns the error is
var $app_list = localStorage.getItem('LsAppList');
var AppListJson = JSON.parse($app_list);
AppListJson.push({
"extapp_id": appdetail.get("addAppId"),
"desc": appdetail.get("addAppName"),
"device_no": appdetail.get("devicenoValue"),
"validation_key": appdetail.get("activationkeyValue")
});
the console log is
Uncaught TypeError: Cannot read property 'push' of null
addToJson EncigoHome.js:126
n.extend.trigger kendo.mobile.min.js:9
s.extend._release kendo.mobile.min.js:15
i._userEvents.o.UserEvents.tap kendo.mobile.min.js:15
n.extend.trigger kendo.mobile.min.js:9
l.extend.notify kendo.mobile.min.js:13
u.extend._trigger kendo.mobile.min.js:13
u.extend.end kendo.mobile.min.js:13
l.extend._eachTouch kendo.mobile.min.js:13
l.extend._end kendo.mobile.min.js:13
arguments.length.t.(anonymous function) kendo.mobile.min.js:10
b.event.dispatch jquery-1.9.1.js:9593
v.handle
localStorage is per domain (more specifically same origin). The localStorage associated with the remote domain does not have access to the values stored in the localStorage associated with your localhost.
You should check to see if there is a stored value and fallback to a default one or treat the error:
var $app_list = localStorage.getItem('LsAppList');
var AppListJson = $app_list != null ? JSON.parse($app_list) : [];
//...
More verbose:
var $app_list = localStorage.getItem('LsAppList'),
AppListJson;
if ($app_list != null) {
AppListJson = JSON.parse($app_list);
} else {
// treat no LsAppList stored case
// you could show a message or set it to a default value
AppListJson = [];
}
This "no previously stored data" scenario will happen whenever the user clears his browser data or switches browsers/devices as well, so it must be treated properly.
The root cause of the error, as you've probably figured out already, is that localStorage.getItem(key) returns null when no value is stored for the given key in the current domain. Then JSON.parse(null) === null and null.push() throws.
Just as a nitpick, I'd suggest reviewing your variables naming:
Don't use PascalCase naming for non-constructors.
Don't mix camelCase with underline naming conventions.
Recommended read: Idiomatic.js naming.
And also, AppListJson is not JSON, it is a native array. JSON can only exist in string context, that is, your $app_list is JSON. More in-depth explanation about JSON/not JSON: There's no such thing as a "JSON Object"
The .push() method can only be used on arrays.
It seems that you don't have the item stored in localStorage, which is why it is returning null