referenceerror in underscore js template - node.js

i am using backbonejs with node js trying to pass variable from backbone view to template(html file). function for rendering view template is like this :
render: function(event){
var compiled_template = _.template( $("#results-template").html() );
console.log(myPhoto.toJSON());
$(this.el).html(compiled_template(myPhoto.toJSON()));
return this;
}
myPhoto having a value :
{
src: 'placeholder.jpg',
title: 'an image placeholder',
coordinates: [0,0],
tags: ['untagged'],
location: 'home'
}
and in html file :
<script id="results-template" type="text/template">
<h2><%= title %></h2>
<p>testing....</p>
</script>
when i am execute it gives an error like
ReferenceError: c:\trello\testApp/views/test.html:19
17| <script id="results-template" type="text/template">
18|
>> 19| <h2><%= title %></h2>
20| <p>testing....</p>
21| </script>
22|
title is not defined
at Object.<anonymous> (eval at <anonymous> (c:\trello\node_modules\ejs\lib\ejs.js:203:1))
at Object.<anonymous> (c:\trello\node_modules\ejs\lib\ejs.js:201:15)
at ServerResponse._render (c:\trello\node_modules\express\lib\view.js:425:21)
at ServerResponse.render (c:\trello\node_modules\express\lib\view.js:318:17)
at c:\trello\testApp\test.js:23:16
at callbacks (c:\trello\node_modules\express\lib\router\index.js:272:11)
at param (c:\trello\node_modules\express\lib\router\index.js:246:11)
at pass (c:\trello\node_modules\express\lib\router\index.js:253:5)
at Router._dispatch (c:\trello\node_modules\express\lib\router\index.js:280:4)
at Object.handle (c:\trello\node_modules\express\lib\router\index.js:45:10)
how to solve this???

Are you sure all your photos have a title? Empty properties can cause this error. You can fix this by adding default values (empty strings for example) in your backbone Model class.

Related

Cannot read properties of undefined (reading 'split'), and i want to do some tags options

<div class="row no-margin video-title">
<h6><i class="fas fa-book"></i> Tags</h6>
</div>
<div class="image">
<ul class="list-unstyled mb-0">
<%
Tags = video.Tags.split(",");
Tags.forEach (function (tag) {
tag = tag.trim(); %>
<li>
<%= tag %>
</li>
<% }) %>
</ul>
</div>
and I receive this error:
TypeError:
E:\livestreaming\video_streaming\views\video-page\index.ejs:374
372|
373|
>> 374| <%- include("side-bar") %>
375|
376| </div>
377| </div>
E:\livestreaming\video_streaming\views\video-page\side-bar.ejs:39
37| <div class="image">
38| <ul class="list-unstyled mb-0">
>> 39| <%
40| Tags = video.Tags.split(",");
41| Tags.forEach (function (tag) {
42| tag = tag.trim(); %>
Cannot read properties of undefined (reading 'split')
at eval ("E:\\livestreaming\\video_streaming\\views\\video-page\\side-bar.ejs":47:35)
at side-bar (E:\livestreaming\video_streaming\node_modules\ejs\lib\ejs.js:692:17)
at include (E:\livestreaming\video_streaming\node_modules\ejs\lib\ejs.js:690:39)
at eval ("E:\\livestreaming\\video_streaming\\views\\video-page\\index.ejs":101:17)
at index (E:\livestreaming\video_streaming\node_modules\ejs\lib\ejs.js:692:17)
at tryHandleCache (E:\livestreaming\video_streaming\node_modules\ejs\lib\ejs.js:272:36)
at View.exports.renderFile [as engine] (E:\livestreaming\video_streaming\node_modules\ejs\lib\ejs.js:489:10)
at View.render (E:\livestreaming\video_streaming\node_modules\express\lib\view.js:135:8)
at tryRender (E:\livestreaming\video_streaming\node_modules\express\lib\application.js:640:10)
at Function.render (E:\livestreaming\video_streaming\node_modules\express\lib\application.js:592:3)
This means that video.Tags stores an undefined value. Make sure to check if the video.Tags has a value before using the split() method. See code below:
var video = undefined;
// Cannot read properties of undefined (reading 'split')
video.split(',');
To check whether your string is undefined or not:
const video = undefined;
if (typeof video === 'string') {
const array = video.split(',');
// Do something ...
} else {
console.log('video is not a string');
}
// You could also use method chaining.
const r = video?.split(',');
console.log(r);
You need to learn to read the error, Elon!
Cannot read properties of undefined (reading 'split')
It is clearly saying, a property named split is attempted to be accessed from an undefined value.
Now, all you have to do is, to check where you are using split in the part of the code that throws the error.
Then you will learn that, it is Tags = video.Tags.split(","); where, split is being used. That means, Tags property in video object is not defined.
Now, you simply need to ensure Tags is present in video object always & it must be a string.

Yahoo Weather API throws 'forEach' error

i decided to go ahead and use the yahoo weather api, in an attempt for it to show the location and then the weather.
app.js code:
** note i replaced the api url location with the term 'query'**
var express = require("express");
var app = express();
var request = require("request");
app.set("view engine", "ejs");
app.get("/", function(req, res){
res.render("weatherSearch");
});
app.get("/results", function(req, res){
var query = req.query.searchTerm;
var url = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22"+query+"%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"
request(url, function(error, response, body){
if(!error && response.statusCode == 200){
var data = JSON.parse(body);
res.render("results", {data: data});
}
});
});
app.listen(process.env.PORT, process.env.IP, function(){
console.log("Server Connected");
});
weatherSearch.ejs :
<h1>Where would you like to check the weather?<h1>
<form action ="/results" method="GET">
<input type="text" placeholder="Enter the city here!" name="searchTerm">
<input type="submit">
</form>
results.ejs
<h1>The Weather is:</h1>
<ul>
<% data["query"].forEach(function(weather){ %>
<li>
<strong>
<% weather["location"] %>
</strong>
</li>
<% }) %>
</ul>
Search Again!
The error i receive from the console is:
Server Connected
TypeError: /home/ubuntu/workspace/WeatherSearchAPP/views/results.ejs:4
2|
3| <ul>
>> 4| <% data["query"].forEach(function(weather){ %>
5| <li>
6| <strong>
7| <% weather["location"] %>
data.query.forEach is not a function
at eval (eval at compile (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/ejs/lib/ejs.js:618:12), <anonymous>:11:22)
at returnedFn (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/ejs/lib/ejs.js:653:17)
at tryHandleCache (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/ejs/lib/ejs.js:251:36)
at View.exports.renderFile [as engine] (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/ejs/lib/ejs.js:482:10)
at View.render (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/express/lib/view.js:135:8)
at tryRender (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/express/lib/application.js:640:10)
at EventEmitter.render (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/express/lib/application.js:592:3)
at ServerResponse.render (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/express/lib/response.js:1008:7)
at Request._callback (/home/ubuntu/workspace/WeatherSearchAPP/app.js:19:21)
at Request.self.callback (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/request/request.js:185:22)
yahoo weather api: (This currently gives the weather in 'london'), so if you copy this in to your web browser you'll see a vast amount of info pertaining to the weather in London.
https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22london%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys
if anyone has any suggestions on what i have done incorrectly that would greatly be appreciated!!
The API returns data in the format of { "query": { ...} }, translate this into a JSON object and you end up with a query object, not an array. Looking at the query object itself it does seem to have count and results properties (and the results property also looks like an object). However, your particular query only yields a single result, so assuming this yields an array in scenarios where you have more than one I presume you'll need to use a combination both of these properties to parse the data accurately e.g.
const data = JSON.parse(body);
const { count, results } = data.query;
res.render("results", {
results: count > 1 ? results : [results] // wrap in an array of only single result
});
Then in your view
<% results.forEach(...) %>
'forEach' is an array method and the Yahoo Weather API doesn't return an array under the key "query". Each API is different, and each request can yield different structured JSON data.
You can check how Yahoo Weather API response is structured by opening this link, as you mentioned. For example, if you want to access the city name, you would use
<%= data.query.results.channel.location.city %>
You get a forecast array returned for the upcoming days, on which you could use a forEach loop because it's an array: query.results.channel.item.forecast
In a scenario where you would want to loop over objects in JS, you can use the for...in loop: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

Knex/Jade: Cannot read property 'length' of undefined

Trying to switch out Mongo and put in Postgres (in other words, similar code worked fine with Mongo). Getting Cannot read property 'length' of undefined on the following code. I'm sure it's simple but I'm new to this whole stack so having trouble tying it together. Not a lot of examples on knex, so even though the docs are pretty good, I'm having trouble finding an example to copy.
I'm obviously pulling the right data but am stuck on how to get jade to display it.
Stack: Node/Express/Knex/Postgres/Jade
users.js
router.get('/', function(req, res, next) {
db.select().from('users').limit(1)
.then(function(users) {
console.dir(users)})
.then(function(users) {
res.render('users', {users: users})})
.catch(function(error) {
console.error(error)
})
});
users.jade
extends layout
block content
h1 Users
ul
for user in users
p
input(type="text", name="name", value="#{user.name}")
input(type="text", name="admin", value="#{user.admin}")
input(type="text", name="smsNumber", value="#{user.smsNumber}")
console
[ { uid: 1,
name: 'Don',
admin: 'true',
smsNumber: '4077023951',
created_at: null,
updated_at: null } ]
browser at localhost:3000/users
C:\Users\dvande03\Personal\dailychallenge\views\users.jade:6 4| h1 Users 5| ul > 6| for user in users 7| p 8| input(type="text", name="name", value="#{user.name}") 9| input(type="text", name="admin", value="#{user.admin}") Cannot read property 'length' of undefined
TypeError: C:\Users\dvande03\Personal\dailychallenge\views\users.jade:6
4| h1 Users
5| ul
> 6| for user in users
7| p
8| input(type="text", name="name", value="#{user.name}")
9| input(type="text", name="admin", value="#{user.admin}")
Cannot read property 'length' of undefined
at eval (eval at <anonymous> (C:\Users\dvande03\Personal\dailychallenge\node_modules\jade\lib\index.js:218:8), <anonymous>:51:31)
at eval (eval at <anonymous> (C:\Users\dvande03\Personal\dailychallenge\node_modules\jade\lib\index.js:218:8), <anonymous>:106:4)
at eval (eval at <anonymous> (C:\Users\dvande03\Personal\dailychallenge\node_modules\jade\lib\index.js:218:8), <anonymous>:119:22)
at res (C:\Users\dvande03\Personal\dailychallenge\node_modules\jade\lib\index.js:219:38)
at Object.exports.renderFile (C:\Users\dvande03\Personal\dailychallenge\node_modules\jade\lib\index.js:380:38)
at Object.exports.renderFile (C:\Users\dvande03\Personal\dailychallenge\node_modules\jade\lib\index.js:370:21)
at View.exports.__express [as engine] (C:\Users\dvande03\Personal\dailychallenge\node_modules\jade\lib\index.js:417:11)
at View.render (C:\Users\dvande03\Personal\dailychallenge\node_modules\express\lib\view.js:126:8)
at tryRender (C:\Users\dvande03\Personal\dailychallenge\node_modules\express\lib\application.js:639:10)
at EventEmitter.render (C:\Users\dvande03\Personal\dailychallenge\node_modules\express\lib\application.js:591:3)
at ServerResponse.render (C:\Users\dvande03\Personal\dailychallenge\node_modules\express\lib\response.js:961:7)
at C:\Users\dvande03\Personal\dailychallenge\routes\users.js:11:13
at tryCatcher (C:\Users\dvande03\Personal\dailychallenge\node_modules\bluebird\js\main\util.js:24:31)
at Promise._settlePromiseFromHandler (C:\Users\dvande03\Personal\dailychallenge\node_modules\bluebird\js\main\promise.js:454:31)
at Promise._settlePromiseAt (C:\Users\dvande03\Personal\dailychallenge\node_modules\bluebird\js\main\promise.js:530:18)
at Promise._settlePromises (C:\Users\dvande03\Personal\dailychallenge\node_modules\bluebird\js\main\promise.js:646:14)
res.render should look like this: res.render(view [, locals] [, callback]), where locals is an object whose properties define local variables for the view.
In your case that means changing the line where you render to:
res.render('users', {users: users})
You pass an object with local variables to render. In the jade-file you use the keys in the object when you want to refer to the values.
Solved it but I don't completely understand why. I commented out the console.dir before the render and it works. Is that because the users in the console.dir .then didn't pass to the render .then?
I accepted the answer above too because without that, I couldn't have gotten here. Thank you #tomtom.

node.js : rendering error with vash

I'm getting a rendering error in node.js with vash. I'm really struggling to see what the issue is. Below is the error and the code causing the error.
TypeError: Problem while rendering template at line 4, character 2.
Original message: object is not a function. Context: 2 |
#html.block('body', function(model){ 3 | <p>#model.title </p> > 4 |
}); 5 | }); 6 | 7 | at helpers.extend.model
(C:\Users\user009\Dropbox\cpp\node_modules\vash\build\vash.js:2213:4)
at Object.vash.loadFile
(C:\Users\user009\Dropbox\cpp\node_modules\vash\build\vash.js:2072:10)
at helpers.extend
(C:\Users\user009\Dropbox\cpp\node_modules\vash\build\vash.js:2190:8)
at eval (eval at <anonymous>
(C:\Users\user009\Dropbox\cpp\node_modules\vash\build\vash.js:1820:24),
<anonymous>:7:21) at vash.link.linked
(C:\Users\user009\Dropbox\cpp\node_modules\vash\build\vash.js:1860:12)
at vash.renderFile
(C:\Users\user009\Dropbox\cpp\node_modules\vash\build\vash.js:2082:21)
at Object.vash.loadFile
(C:\Users\user009\Dropbox\cpp\node_modules\vash\build\vash.js:2070:10)
at View.vash.renderFile [as engine]
(C:\Users\user009\Dropbox\cpp\node_modules\vash\build\vash.js:2078:8)
at View.render
(C:\Users\user009\Dropbox\cpp\node_modules\express\lib\view.js:76:8)
at Function.app.render
(C:\Users\user009\Dropbox\cpp\node_modules\express\lib\application.js:502:10)
router:
app.get("/", function (request, response) {
response.render('index', {title: 'letsdoit'});
});
layout.vash
<!DOCTYPE html>
<html>
<head><link href="/css/site.css" rel="stylesheet" />
<title>#model.title</title></head>
<body><div> #html.block('body') </div></body></html>
index.vash
#html.extend('layout', function(model){
#html.block('body', function(model){
<p>#model.title </p>
});
});
In your index.vash file, make sure the path to the layout.vash file is correct.
For example, if the views folder structure is views/home/layout.vash and views/home/index.vash, then:
#html.extend('layout', function(model){
should be:
#html.extend('home/layout', function(model){
hope it helps.

templateData variables return undefined from helper function (docpad.coffee configuration file)

This is my configuration file.
docpadConfig = {
templateData:
site:
title: 'hello docpad'
getTitle: ->
#site.title
getString: ->
'just a string'
}
# Export the DocPad Configuration
module.exports = docpadConfig
From a jade layout when I do title= site.title it renders ok. When I try to call the helper function title= getTitle() the console outputs this:
error: An error occured:
ReferenceError: /Volumes/Data/project/am/lab/docpad/hello_docpad/src/layouts/default.html.jade:21
19|
20| //- Our site title and description
> 21| title= getTitle()
22|
23| //- Output DocPad produced meta elements
24| != getBlock('meta').toHTML()
site is not defined
at docpadConfig.templateData.getWat (/Volumes/Data/project/am/lab/docpad/hello_docpad/docpad.coffee:10:16)
at eval (eval at <anonymous> (/Volumes/Data/project/am/lab/docpad/hello_docpad/node_modules/docpad-plugin-jade/node_modules/jade/lib/jade.js:170:8), <anonymous>:47:64)
Looks like I can't access the site object from inside the helper function.
I'm sure I'm missing something trivial, maybe a plugin is needed for this... can't find out "wat" is wrong here.
I've found the solution looking into a similar issue in a docpad skeleton. This relates to a bug in the Jade pre-processor.
Update to "docpad-plugin-jade": "~2.4.1" fixes the issue.

Resources