I'm aware that there are a lot of questions asking the same thing but none of those answers seem to work for my specific case and I have been at this for hours and still can't figure it out. I'm following a ReactJs tutorial for a WeatherApp.I get back an object from an API call that looks like this:
{
current: {}
forecast:
forecastday:[ //
0: {...}
1: {...}
2: {...}
3: {...}
4: {...}
] //Array of five objects
location: {}
} //this object is part of a bigger response object
When I console.log(objectName.forecast.forecastday) I get back the array, which means it's actually there.
But when I try
var forecastData = props.forecast.data;
var days = forecastData.forecast.forecastday.map(function (day) {
//do something
});
it gives me back the error Uncaught TypeError: Cannot read property 'forecast' of undefined. I have also tried logging forecastData and it comes back just fine. forecast is clearly there so unless I'm missing something extremely obvious, I don't know what's going on.
Thanks.
You are most likely not taking into account the initial state, where props.forecast.data may be undefined at the initial mount of the component since your API call is happening asynchronously.
You can do something like this:
var days = forecastData
? forecastData.forecast.forecastday.map(function (day) {
//do something
})
: null;
This will first check to see if forecastData exists, and if it does exist, it will map over the forecastData.forecast.forecastday array.
If forecastData does not exist, then that variable will render null.
Related
I have a problem, when I add an element in my bdd and my view client (with $set), a function is called. But I have error for accessing data, with the console.log, I see the new data is added but the data inside the object is not.
This is my error:
vue.esm.js?efeb:610 [Vue warn]: Error in render: "TypeError: Cannot read property 'id' of undefined"
for (var i = 0; i < this.assignments.length; i++) {
var date1 = new Date(date);
var date2 = new Date(this.assignments[i].start);
if (user === this.assignments[i].User.id) {
The error is saying that you are accessing an undefined value in this case the User of this.assignments[i].User is undefined.
Edit : To be sure check every thing
if (this.assignments && this.assignments[i] && this.assignments[i].User && user === this.assignments[i].User.id)
Well..
If I see problem like this, I am always trying to put debugger right after console.log in order to stop executing script. Don't always trust console.logs someone somewhen said.
Probably with that debugger, console.log will show something different, and that's because it's holding reference, so it's filled later. (you will be able to see that in the console)
Anyway...
What You can try to do for sure is
await this.$nextTick() - waiting for next render, then continue
Put it right before your not working code.
If not you can try forbidden technique - to wrap your code in
setTimeout(()=>{
...your code which needs to wait for render
},0)
I am running into an issue in my Angular 2 app where I'm getting an undefined error that's not making sense to me. What's more perplexing is that, after getting the undefined error, I can effectively check the exact same value in the console and get it with no issues.
First off, here's a version of the function that DOES work:
public getApplicableResult()
{
if (!this.customer || !this.customer.services || !this.customer.services.getAt(0))
{
console.log('Services not available...');
return;
}
else if (this.customer && this.customer.services && this.customer.services.getAt(0))
{
console.log(this.customer.services.getAt(0));
}
When I run this function I get this in the console for my "console.dir" of my object literal:
CustomerServiceDetails
assignments:(...)
authorizations:(...)
If I then click on "assignments" in the console, I get this expanded result:
assignments:
CustomerAssignmentCollection
count:1
items:Array(1)
So all the data is seemingly there and available.
However, if, in my function, if I were to try and access these nested values more directly - such as the value for "count" above, I get an undefined error. That's what I'm not understanding. Perhaps it's something I misunderstand about how the console works. But if seems to me that if I can access the value for this property in the console, then I should be able to access it directly via my function.
Here's an example of the same function, slightly altered to get the result for "count" within assignments, that returns undefined:
public getApplicableResult()
{
if (!this.customer || !this.customer.services || !this.customer.services.getAt(0).assignments)
{
console.log('Services not available...');
return;
}
else if (this.customer && this.customer.services && this.customer.services.getAt(0).assignments)
{
console.dir(this.customer.services.getAt(0).assignments.count);
}
The specific error I get is:
Cannot read property 'assignments' of undefined;
To add some additional info, assignments is not an array, it's a collection.
Two questions here:
1.) Why isn't my first "if" clause handling the 'undefined' error? How could I adjust it to handle the situation better?
2.) Why can I call the first function, get a result, and then drill down from there in the console to get what I need, but if I try and access a more nested part of the object in the function itself, I get undefined as a result?
One additional detail, I was calling this via Angular's ngAfterViewChecked(). So what that should do, even if it's a timing issue, is return the first "if" else clause result until the value is available, and then it should show the result - i.e., it should execute the "else if" block - because AfterViewChecked() keeps checking. But this isn't happening. I'm just getting the undefined result I mentioned above.
I have the following React class. At first, the console will print an empty array {}, which will return the empty div. However, half a second later the console will print the correct values - but the empty div remains. How should I change the class to properly load the JSON?
var TableData = React.createClass({
render: function() {
console.info(JSON.stringify(this.props.summary));
if (!this.props.data || !this.props.summary) {
return <div>Loading name table..</div>
}
var summary = this.props.table;
var nameTable = summary.nameTable;
var nameTableArr = Object.values(nameTable);
return ( // A table is returned here, works with the same data structure as is present in the JSON
If I go to the console, the console.info prints an empty JSON string {} initially, which correctly returns the "loading names table..." div. However, data is printed in the console half a second later, but it never proceeds to go out of the if statement and populate the table.
It works if I change the nameTable var to include "manual" data, so it must be something with rendering the server-side data that's delayed half a second.
How could I change the above class to delay rendering for, say, 1 second and then populate the table? It would work in that case I suspect.
Removing the if statement results in Uncaught TypeError: Cannot convert undefined or null to object in the console, which makes sense since the string is indeed empty for half a second.
Im not a React experienced, but this looks like you have problem with asynchronous behavior.
In order to help you more, Ill need the part of the code where ajax is called.
The whole issue in my opinion is that your code is triggered first when there are no results yet, and after data are loaded it will not trigger again.
So take a closer look at your handling of AJAX async stuff, cause your issue is there.
The title might not be the best way to describe the problem, but I was wondering if there was a better practice to declaring an object in getDefaultProps?
In my render method I call several keys from from a prop/state that get updated on a click event i.e. this.props.player.name. The problem is that on page load this.props.player is blank and calling .name errors out. I know I can do something like ...
getDefaultProps: function() {
return {
player: {
name: null,
team: null
position: null
}
};
}
but it doesn't feel right. I was hoping there might be something similar to how Ruby does .try() where it won't try to call a method on a undefined prop.
The problem is specifically that this.props.player is undefined, if you define an empty object it will prevent the error from occurring. It's not bad practice to stub out the keys you're anticipating, but setting the default value to {} will be enough to prevent it from throwing.
You can create your data from ImmutableJS. Then you can get any part of your data like this:
this.state.getIn(['player', 'name', ...])
or
this.state.get('player')
This will not throw error even player is not defined or other, it will return undefined (or null) I don't remember
The update and updateIn work the same
see the doc here
I'd like to add this vanilla JS solution too - var x = (user || {}).name;
Source
I asked a question yesterday, but I've kept going with it. Instead of calling next() and passing an an Error object, I worked out what it was doing, and tried to copy it. Now, when someone logs in and it fails, I do this:
res.render("pages/home",
{
flash:{"danger":["Login failed. Please enter your details and try again."]},
body:{},
section:"home",
locals : { userId : req.body.email }
}
This does exactly the same thing as the old code. I step through it, and I can see that the locals object contains a property called userId, with the value I expect. In the Jade template, I have this:
p it's #{typeof(userId)}
if(typeof(userId) != 'undefined')
p Welcome #{userId}
input(type='text', name='email', id="inputEmail", placeholder="Email", value="#{userId}")
else
input(type='text', name='email', id="inputEmail", placeholder="Email", value="")
This always renders as 'it's undefined' and then an empty text box. I have read several questions on this, and as far as I can see, they all say the same thing: if I set locals to be a JSON object, I can access it's properties by this syntax, but it does not work.
What am I doing wrong ?
You might first need to better understand how locals object actually work.
On the server-side, doing this:
res.render('view', { property: 'value' } );
would make property available in your views like so:
div Value = #{property}
You can also do the following to have the same effect:
res.locals.property = 'value';
res.render('views');
Note the usage of locals object. More info
Coming back to your issue, since you have
res.render("pages/home", { locals: { userId : req.body.email } })
to access userId in this case you would do:
p Welcome #{locals.userId}
So I'm guess you're confusing the two approaches ending up using locals object the wrong way.
OK - turns out that 'locals' doesn't mean anything any more. Leaving my code as it is, I needed to access 'locals.userId', but I could have just set the value of 'userId' and not had the 'locals' object at all.