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.
Related
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.
You have a json object.
By mistake you pass some element (property1) to a function and the value passed doesn't exists...
myFunction (json.propety1); // it must be 'property1' , with r
I'd like to set any configure element to say the browser "I can't pass undefined json properties, rise an error"
I think this is not possible, is't it ?
Thanks in advance
in myfunction you can check for undefined and then do something
like
function myFunction(jsonproperty){
if(jsonproperty === undefined){
//do something with the DOM to pass whatever you wanna say in the browser
}
}
Is that what you were trying to do? You could also throw an exception like this:
throw "json property was undefined"
but you would only see that in some kind of js debugger console. Nowadays all browser have one. Usually accessible with "F12"
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
My html code:
<template name="homeItem">
<li class= "{{selectedClass}}">{{{content}}}</li>
<li class= "tagsBody">{{#each tags}}{{tags}} {{/each}}</li>
</template>
The subscribing to "contents" is being done at the route controller level.
Now the "tags" is an array which is a part of "content" which is a document in a collection named "contentsList".
I have used a homeitem helper function which goes such as this:
JS client code
Template.homeItem.helpers({
'tags':function(){
return contentsList.findOne({_id: this._id}).tags
}
});
The errors that are returned are:
1) Exception in template helper: TypeError: Cannot read property 'tags' of undefined.
2)Uncaught Error: {{#each}} currently only accepts arrays, cursors or falsey values.
3)Exception from Tracker recompute function:TypeError: Cannot read property '0' of null
How can I solve this problem? I am new to programming. So, please forgive me for diverting from any programming conventions. Any help would be hugely appreciated.
contentList.findOne({_id: this._id}) is returning null, so when you try to do null.tags it shows up as undefined.
Make sure that a subscription exists for contentsList and that you can search it. Test this by running contentList.find().fetch() to see what comes back. If nothing comes back, your subscription doesn't exist.
I have a subclass called TreeFolderObject. One of the column headings is called "parent" and is a pointer field. It points to other another object in the same class. Here is the stripped down code I am using to attempt to read data from this structure:
var TreeFolderObject = Parse.Object.extend('TreeFolderObject');
var folderQuery = new Parse.Query(TreeFolderObject);
folderQuery.include("parent");
folderQuery.find().then(function(results) {
for (i in results) {
treeData.push({
title: results[i].get('folderName'),
objectId: results[i].id,
parent: results[i].get("parent")
});
console.log(results[i].get("parent").get("folderName") );
}
},
function(error) {
console.log("failed, with error code: " + error);
}
);
The console line reports the following output:
Uncaught TypeError: Cannot read property 'get' of undefined
I have also tried shortening the console.log line to just:
console.log(results[i].get("parent") );
and this reports the following:
undefined
index.html:100
ParseObjectSubclass {className: "TreeFolderObject", _objCount: 32, id: "oq5o2zFqIM"}
index.html:100 ParseObjectSubclass {className: "TreeFolderObject", _objCount: 24, id: "oq5o2zFqIM"}
index.html:100 ParseObjectSubclass {className: "TreeFolderObject", _objCount: 41, id: "oq5o2zFqIM"}
etc
This indicates that the browser client is obtaining the information I am after. I just can't work out how to get the data "out", if that makes sense.
Ultimately, I want to identify the parent object of each object so I can iterate through the class.
What I am doing wrong? I have tried searching here and on the web in general and there are a lot of very similar questions. This is obviously a confusing topic. I just can't work it out though and any help would be much appreciated. How do I get the console to print out the folderName property of the parent object?
Here's a screenshot of the parse control panel, if that helps:
enter image description here
Add "var" in front of i like this
var TreeFolderObject = Parse.Object.extend('TreeFolderObject');
var folderQuery = new Parse.Query(TreeFolderObject);
folderQuery.include("parent");
folderQuery.find().then(function(results) {
for (var i in results) {
treeData.push({
title: results[i].get('folderName'),
objectId: results[i].id,
parent: results[i].get("parent")
});
console.log(results[i].get("parent").get("folderName") );
}
},
function(error) {
console.log("failed, with error code: " + error);
}
);
Answering my own question here:
I eventually discovered the answer, and its got nothing to do with labeling i as a var, or the fact that I'm querying the same class. The solution is to put a condition line in the query. In other words, insert this after the first two lines of the code I posted earlier:
folderQuery.exists("parent");
In my case every object in the class, apart from one, has a parent, so this works fine. What I don't understand is why it should be necessary to put a condition on the query at all, if I'm intending to query the entire class.
I discovered the solution after browsing lots of parse pointer related questions on StackOverflow. No one else seems to have fallen into the exact same trap of leaving out the condition line, and eventually I realised that my parse query wasn't following the convention. If this realisation helps anyone else out there, I will be happy to have helped!
If anyone can help with an explanation as to why I need to put a condition line in, even though I'm querying the entire class, please let me know. In the meantime, I'm happy to have found this solution as it was holding up development of my project.