I want to put the fallowing in a helper but i get and require it in my app.js. My current error is app is not defined. I am new to node.js so if this is a easy one dont be to hard on me.
app.locals.use({flashMessages: function(req, res) {
var html = ""
, flash = req.flash();
['error', 'info'].forEach(function(type) {
if(flash[type]) {
flash[type].forEach(function(message) {
html += "<div class='alert " + type + "'>" + message + "</div>";
});
}
});
return html; }});
You should either convert this to a function that accepts an app parameter, or you could put app into GLOBAL. See node.js global variables?
Related
This is my app.js:
const express = require("express");
//const https = require("https");
const app = express();
app.get("/", function(req, res) {
const query = niall;
// Follow procedure here to get access_token and refresh_token: https://benwiz.com/blog/create-spotify-refresh-token/
const access_token = {access_token};
const token = "Bearer " + access_token;
var searchUrl = "https://api.spotify.com/v1/search?q=" + query + "&type=track&limit=4";
////////WRITE YOUR CODE HERE//////////
});
// Starting the server. Should this be placed at the top of all other commands?
app.listen(3000, function() {
console.log("Server is running on port 3000.")
})
Expected Behaviour:
We are to get results from the api endpoint using https.get method.
The returned data is to be parsed to JSON.
We need to store the value of track ID, from this JSON output, into a variable and log it in the console.
Helpful Resources:
Follow the steps here to get the access_token: https://benwiz.com/blog/create-spotify-refresh-token/
Understand parameters here: https://developer.spotify.com/documentation/web-api/reference/#category-search
Spotify Web Console to understand the JSON arrangement: https://developer.spotify.com/console/get-search-item/
I'm really in need of help. Any help would be appreciated.
Replace ////////WRITE YOUR CODE HERE////////// with
axios.get(searchUrl, {
headers: {
'Authorization': token,
}
})
.then((resAxios) => {
console.log(resAxios.data)
spotifyResult = resAxios.data;
//Extracting required data from 'result'. The following "items[0].id.videoId" is the address of the data that we need from the JSON 'ytResult'.
let spotifyTrackIdAppJs00 = spotifyResult.tracks.items[0].id;
let spotifyAlbumIdAppJs00 = spotifyResult.tracks.items[0].album.id;
let spotifyArtistIdAppJs00 = spotifyResult.tracks.items[0].artists[0].id;
console.log("Fetched values: " + spotifyTrackIdAppJs00 + ", " + spotifyAlbumIdAppJs00 + ", " + spotifyArtistIdAppJs00);
// The 'results' named EJS file is rendered and fed in response. The 'required' data is passed into it using the following letiable(s).
// A folder named 'views' has to be in the same directory as "app.js". That folder contains 'results.ejs'.
res.render("results", {
spotifyTrackIdEjs00: spotifyTrackIdAppJs00,
spotifyAlbumIdEjs00: spotifyAlbumIdAppJs00,
spotifyArtistIdEjs00: spotifyArtistIdAppJs00
});
console.log("Values to be used in rendered file: " + spotifyTrackIdAppJs00 + ", " + spotifyAlbumIdAppJs00 + ", " + spotifyArtistIdAppJs00);
})
.catch((error) => {
console.error(error)
})
I needed ID value for Album and Artist as well. Please modify accordingly.
When I create a JsonClient in node I do the following:
var client = restify.createJsonClient({
url: 'https://www.domain.com:4321/api'
});
Once I've done that, I make calls like so:
client.post('/service/path', { });
Which seems right. I expect that the path called would be something like https://www.domain.com:4321/api/service/path. However, what is happening is that the client is throwing away the /api base path and calling https://www.domain.com:4321/service/path.
I don't get it - I'm inserting the client URL into a config file, so that I can change hosts without any hassle; Now that I need a base path, I need to change the code as well as the config.
If you put a wrapper around the restify JsonClient stuff you could do it with minimal code change and the config would, I think, work the way you want it.
Create a library file myClient.js
'use strict';
var restify = require('restify');
var jsonClient = null;
module.exports = {
createJsonClient: function(opts){
var opts = opts || {};
var url = opts.url;
var parts = url.split('/');
var main_url = parts[0] + '//' + parts[2];
var basePath = parts[3] ? parts[3] : '';
jsonClient = restify.createJsonClient({url: main_url});
return {
get: function(path, cb){
var adjusted_path = '/' + basePath + path;
jsonClient.get(adjusted_path, function(err2, req2, res2, obj2){
return cb(err2, req2, res2, obj2);
});
}
}
}
}
Then use it like this.
var myClientWrapper = require('./lib/myClient');
var client = myClientWrapper.createJsonClient({url: 'http://localhost:8000/api'});
client.get('/service/path/one', function(err, req, res, obj){
if(err){
console.log(err.message);
return;
}
console.log(res.body);
});
It could use some more error checking and the url parsing is a little brittle, but it does work. I tried it out. Of course, I only wrapped the get function but you can see how it would work for the others.
I wanted to remember the last page someone visited (like here)
I tried to do it with cookie-session but It's doesn't work as I a suppose.
I saw this and I tried this example for extending the session without success.
Here the code :
var session = require('cookie-session');
var express = require('express');
var app = express();
app.use( session({ secret: 'secret' }) );
app.get('/a', function (req, res) {
if(req.session.last) {
res.write("the last page was " + req.session.last + ". ");
}
req.session.last = "a";
res.end("Page A");
});
app.get('/b', function (req, res) {
if(req.session.last) {
res.write("the last page was " + req.session.last + ". ");
}
req.session.last = "b";
res.end("Page B");
});
app.get('/c', function (req, res) {
if(req.session.last) {
res.write("the last page was " + req.session.last + ". ");
}
req.session.last = "c";
res.end("Page C");
});
app.listen(8080);
Are you sure you are not getting an error in your logs along the line of "cannot write to headers after they have been sent"? Can you try moving the assigning of the session to before the res.write call? From your first link, in the comments...
"I kept getting an error that the headers couldn't be set after they'd been sent.
I modified the code so that lastPage was set before sending any body eg:
var responseText;
if(req.session.lastPage)
responseText = 'Last page was: ' + req.session.lastPage + '. ';
else
responseText = 'You\'re Awesome';
req.session.lastPage = '/awesome';
res.send(responseText);
My controllers looks like this in usermains.js
var header = function (req, res, next) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.locals.title="helloooo";
res.write(loadView('headerpage'));
console.log(res.title);
next();
};
app.get('/log',header,values,renderBody);
Here is my loadview function
var loadView = function(name, locals) {
if(name=='main'){
console.log(path.join('views/layouts/'+name + '.hbs'));
var template = fs.readFileSync(path.join('views/layouts/'+name +'.hbs')).toString();
}else{
console.log(path.join('views/'+name + '.hbs'));
var template = fs.readFileSync(path.join('views/'+name + '.hbs')).toString();
}
return template;
};
And i am calling this on view page.
{{title}}
It is giving output as {{title}} on browser. How to get res.locals.title value on view page. Thanks!
Use Handlebars in order to first compile, and then execute the template, passing the appropriate data that you wish. Simply reading/loading the template will give you the raw data. Use something like (tweak it for your needs, this is only a sample):
var handlebars = require('handlebars');
var rawTemplate = fs.readFileSync(path.join('views/'+name + '.hbs')).toString();
var compiledTemplate = handlebars.compile(rawTemplate);
var result = compiledTemplate(dataPassedToTemplate);
res.write(result);
I am using using EJS templates with Node.js and Express. I am trying to pass a request parameter to my EJS template. It is working, however, for some reason my console log is reporting something strange.
Versions:
Node 0.10.26
Express 4.6.1
EJS 0.8.5
Here is the route that handles the ejs template:
var express = require('express');
var router = express.Router();
var data = require('../data.json');
var pkg = require('../../package.json');
router.get('/', function(req, res) {
res.render('index',
{
'acs' : data.acs,
'products' : data.products,
'pkg' : pkg,
'debug' : req.param('debug')
});
});
module.exports = router;
This is the console log (I replaced anything long with "..." to save space)
var __stack = {
lineno: 1,
input: "<!DOCTYPE html>\n<html lang=\"en\"> ... </html>\n",
filename: "/web/app/views/index.ejs" };
function rethrow(err, str, filename, lineno){
var lines = str.split('\n')
, start = Math.max(lineno - 3, 0)
, end = Math.min(lines.length, lineno + 3);
// Error context
var context = lines.slice(start, end).map(function(line, i){
var curr = i + start + 1;
return (curr == lineno ? ' >> ' : ' ')
+ curr
+ '| '
+ line;
}).join('\n');
// Alter exception message
err.path = filename;
err.message = (filename || 'ejs') + ':'
+ lineno + '\n'
+ context + '\n\n'
+ err.message;
throw err;
}
try {
var buf = [];
with (locals || {}) { (function(){
buf.push('<!DOCTYPE html>\n<html lang="en">...</html>\n'); })();
}
return buf.join('');
} catch (err) {
rethrow(err, __stack.input, __stack.filename, __stack.lineno);
}
Like I said, it is working, however I can't tell why this is being logged in the console. Thanks for the help!
The problem is that the second argument passed to res.render() is passed to both the rendering engine AND your template. Because of this behavior, ejs (at least through 1.0 as of this writing), looks for a debug property in that object to determine if debug information will be printed.