Jade with Express - how to disable ReferenceError - node.js

i want replace empty string instead of ReferenceError. following code :
p #{data.data.data}
ReferenceError occured when render template that i want disable it.

Stumbled onto the same thing, but passing an empty object felt wrong. I suggest handling the possibility in the template with something like:
- if(data)
p #{data.data.data}
- else
p No data for you!
Or specify a placeholder inline
p #{data.data.data ? data.data.data : 'No data'}

Pass an empty object if there is no value when rendering:
res.render('view/index', {data: your_data_variable || {} });

Related

"Cannot read property 'map' of undefined" react and node.js

https://github.com/dongha1992/MERN-boilerplate
enter image description here
hello. currently I tried to practice shopping mall clone as react and node.js
I faced that problem I attached. it doesn't seem that error for cos I copied same as tutorial but it is something wrong with node.js(localhost:5000)
I tried to everything to fix it but don't know how to approach. please help me!
enter image description here
Probably an asynchronous request that populates your props.images hasn't returned a response.
Prefix props.images && to props.images.map function
That way only when the prop is present does the the map occur. Like this
{props.images && props.image.map(image=>.........
Ok, this is often an issue of a variable taking on different value during code execution. To safeguard again this, it's recommended to make sure that the props or a specific variable is defined before it's used.
// alternative-1
function ImageSlider(props){
return props.images && (
<div>
<Carousel autoplay>
{props.images.map((image, index) =>
// ...
)}
// ...
</div>
);
};
OR
// alternative-2
function ImageSlider(props){
return props.images ? (
<div>
<Carousel autoplay>
{props.images.map((image, index) =>
// ...
)}
// ...
</div>
) : null;
};
Critically, here's what is happening in the return() statement.
Alternative-1 (Implicit):
The second part, <div> is only rendered if the first part is true.
In core JavaScript, undefined is equivalent to false so props.images is true only when images is !undefined (not undefined; in other words, images is defined).
Alternative-2 (Explicit):
This one is more direct, as long as props.image is undefined, we return null.(Remember, a valid react component must return something. If nothing, then return null)
Only when props.images is defined, then we return the <div>.
These added checks ensure that your code never breaks, in this case your map() will always be called on a defined variable (props.images).
Here's a good read on Conditional rendering from the react team.
It looks like you're trying to call the map function on data that hasn't been received from your axios request. You should add some logic so that any components that rely on your request data render only if it exits, easily done with a ternary operator.
It looks like many components (including imageSlider) depend on data you try to access when you call your renderCards function on line 54 of your App.

NodeJS (gettting error notes.push is not a function)

When I run this code I get push is not a function. I have gone over the code so many times and can't figure out where I went wrong. i have also read many of post and I still can't figure it out. I am new to programming and could use the help.
const fs= require('fs')
const getNotes = function() {
    return 'This just returns get notes'
        
enter code here
};
const addNote  = function (title, body) {
    const notes = loadNotes()
    
    notes.push({
        title: title,
        boby: body
    })
    saveNotes(notes)
    
};
const saveNotes = function (notes) {
    const dataJSON = JSON.stringify(notes)
    fs.writeFileSync('notes.json',dataJSON)
}
// Code below loads the notes. Above, addNote adds the note.
const loadNotes = function () {
    try {
        const dataBuffer = fs.readFileSync('notes.json')
        const dataJSON= dataBuffer.toString()
        return JSON.parse(dataJSON)
    } catch (error) {
        return('Note such file')
    }
    
    
}
module.exports ={
    getNotes: getNotes,
    addNote: addNote
}
So, you have this:
const notes = loadNotes()
notes.push({
title: title,
boby: body
});
If you're getting an error that notes.push is not a function, then that is because loadNotes() is not return an array. That could be for a couple reasons:
JSON.parse(dataJson) successfully parses your json, but its top level object is not an array.
JSON.parse(dataJson) throws and you end up returning a string instead of an array.
You can fairly easily diagnose this by adding a console.log() statement like this:
const notes = loadNotes();
console.log(notes); // see what this shows
notes.push({
title: title,
boby: body
});
FYI, returning a string fromloadNotes()as an error really doesn't make much sense unless you're going to check for a string after calling that function. IMO, it would make more sense to either return null for an error or just let it throw. Both would be simpler and easier to check after calling loadNotes().
And, in either case, you must check for an error return value after calling loadNotes() unless you want loadNotes() to throw upon error like it is.

Jade/Pug - appending to a class name

Hello I have a unique id in an object and I want to append it to a class name. I am trying to do something like the following but it isn't working:
myJadeFile:
.googleChartContainer-#{attendanceAnalytics.uid}
myRoute.js:
res.render('./edu/school_dashboard_elementary', { attendanceAnalytics:attendanceChart });
I suppose I could create a class name in my route and send it as a variable with something like:
var className = '.googleChartContainer-attendanceChart.uid}';
res.render('./edu/school_dashboard_elementary', { attendanceAnalytics:attendanceChart, attendanceClassName:className });
and then in the jade file:
#{attendanceClassName} //- output is .googleChartContainer-someUid?
I was wondering if there was a way to get the first approach to work correctly, or if there is another preferred way.
Thanks!
You have two choices. You can do it the JavaScript way with a string, like:
div(id=attendanceAnalytics.uid, class='googleChartContainer-' + attendanceAnalytics.uid)
or you create an JavaScript object containing keys and values to use them with the typical jade attribute div&attribute(object), like this:
- var attr = {"id": attendanceAnalytics.uid, "class": 'googleChartContainer-' + attendanceAnalytics.uid}
div&attribute(attr)
Take a look into the JadeLang Docs, chapter attributes.

node ejs reference error data not defined at eval when handing data to view

i've been closing in on a node application using express and ejs, but when i try to hand data to my view from the controller like so
var myData = {
theData: data
};
res.render(path.join(__dirname + '/../views/index'), myData);
i get a nice error
ReferenceError:.. myData is not defined eval (from ejs lib)
when trying to access myData in the view like so
var data = <%-myData%>;
or in any other way basically, i've tried stringifying the data, wrapping it in another object and stuff like that but it still just won't show up, i have the feeling i'm missing something really basic here, does anyone have an idea on how to fix this?
The second argument you pass to render() is an object containing the view variables you want to use in your template. So the error you are seeing makes sense. If you want to use myData in that way you'd have to do something like this in your controller/app:
res.render(..., { myData: JSON.stringify(myData) });
There's a silly mistake I make when I try to send data from the server.
Here's the mistake:
var data = <%=myData%>;
What you should do when passing it:
var data = <%-myData%>;
It's supposed to be a dash NOT an equal before the variable name.
If your are generating the template with the HtmlWebpackPlugin plugin, the data should be passed in your webpack configuration file, along with the templateParameters property.
For example:
...
plugins: [
new HtmlWebpackPlugin({
filename: __dirname + "/src/views/index.ejs",
template: "./src/views/index_template.ejs",
templateParameters: {
myData,
},
}),
],
...

Cannot access properties on a populate()'d object from Mongoose?

This is very odd... I'm using populate() with a ref to fill in an array within my schema, but then the properties are inaccessible. In other words, the schema is like this:
new Model('User',{
'name': String,
'installations': [ {type: String, ref: 'Installations'} ],
'count': Number,
}
Of course, Insallations is another model.
Then I find & populate a set of users...
model.find({count: 0}).populate('installations').exec( function(e, d){
for(var k in d)
{
var user = d[k];
for(var i in user.installations)
{
console.log(user.installations[i]);
}
}
} );
So far so good! I see nice data printed out, like this:
{ runs: 49,
hardware: 'macbookpro10,1/x86_64',
mode: 'debug',
version: '0.1' }
However, if I try to actually ACCESS any of those properties, they're all undefined! For example, if I add another console log:
console.log(user.installations[i].mode);
Then I see "undefined" printed for this log.
If I try to operate on the object, like this:
Object.keys(user.installations[i]).forEach(function(key) { } );
Then I get a typical "[TypeError: Object.keys called on non-object]" error, indicating that user.installations[i] is not an object (even though it is outputted to the console as if it were). So, I even tried something ugly like...
var install = JSON.parse(JSON.stringify(user.installations[i]));
console.log(install, install.mode);
And, again, the first output (install) is a nice object containing the property 'mode'... but the 2nd output is undefined.
What gives?
Finally, I solved this...
I tried doing a console.log(typeof user.installations[i]); and got "string" as the output. This seemed odd, given that printing the object directly created console output (above) that looked like a normal object, not a string. So, I tried doing a JSON.parse(); on the object, but received the error "SyntaxError: Unexpected token r"
Finally, I realized what was going on. The "pretty console output" I described above was the result of a string formatted with \n (newlines). I had not expected that, for whatever reason. The JSON.parse() error is due to the fact that there is a known necessity with the node.js parser when attempting to parse object keys without quotations; see the SO question here:
Why does JSON.parse('{"key" : "value"}') do just fine but JSON.parse('{key : "value"}') doesn't? .
Specifically, note that the JSON parser in my case is failing on the character 'r', the fist character of "runs," which is the first key in my JSON string (above). At first I was afraid I needed to get a custom JSON parser, but then the problem hit me.
Look back to my original schema. I used a String-type to define the installation ref, because the array field was storing the installations's _id property as a String. I assume the .populate() field is converting the object to a String on output.
Finally, I looked at the Mongoose docs a little closer and realized I'm supposed to be referencing the objects based upon Schema.ObjectID. This explains everything, but certainly gives me some fixing to do in my schemas and code elsewhere...

Resources