Express - Cannot access 'Database' before initialization - node.js

const express = require('express');
const upload = require("express-fileupload");
const editJsonFile = require("edit-json-file");
const fs = require('fs');
const app = express();
app.use(upload())
app.use(express.urlencoded({ extended: true }))
const playlist = editJsonFile(`${__dirname}/playlist.json`);
app.post("/upload", (req, res) => {
//Save file from the html form to ./mp3
var file = req.files.file;
req.pipe(fs.createWriteStream("./mp3/" + file.name));
res.send("File uploaded");
playlist.append("playlist", file.name)
playlist.save()
}),
app.get("/playlist", (req, res) => {
console.log(playlist.get("playlist"))
let playlist = playlist.get("playlist")
let html = "";
for (let i = 0; i < playlist.length; i++) {
html += `<br>${playlist[i]}`;
}
res.send(html);
}),
Hey,
Im trying to make a music player, but somehow I get the error:
ReferenceError: Cannot access 'playlist' before initialization
at C:\Users\Jakob\Documents\Bots\API\PiMusicPlayerV2\index.js:20:17
at Layer.handle [as handle_request] (C:\Users\Jakob\Documents\Bots\API\PiMusicPlayerV2\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\Jakob\Documents\Bots\API\PiMusicPlayerV2\node_modules\express\lib\router\route.js:144:13)
at Route.dispatch (C:\Users\Jakob\Documents\Bots\API\PiMusicPlayerV2\node_modules\express\lib\router\route.js:114:3)
at Layer.handle [as handle_request] (C:\Users\Jakob\Documents\Bots\API\PiMusicPlayerV2\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\Jakob\Documents\Bots\API\PiMusicPlayerV2\node_modules\express\lib\router\index.js:284:15
at Function.process_params (C:\Users\Jakob\Documents\Bots\API\PiMusicPlayerV2\node_modules\express\lib\router\index.js:346:12)
at next (C:\Users\Jakob\Documents\Bots\API\PiMusicPlayerV2\node_modules\express\lib\router\index.js:280:10)
at urlencodedParser (C:\Users\Jakob\Documents\Bots\API\PiMusicPlayerV2\node_modules\body-parser\lib\types\urlencoded.js:91:7)
at Layer.handle [as handle_request] (C:\Users\Jakob\Documents\Bots\API\PiMusicPlayerV2\node_modules\express\lib\router\layer.js:95:5)
I can write to the Database without any issues, but when I try to read from it I get the error above, what can I do?

app.get("/playlist", (req, res) => {
console.log(playlist.get("playlist"))
let playlist = playlist.get("playlist")
The second line console.log(playlist.get("playlist")) is trying to print the playlist variable but its declared in the next line, hence no access to that particular variable ergo the error. You can only access something after it has been initialized.

I think you are overwriting the playlist variable. The file is playlist and when you get the element you assign it to playlist as well
Also, a file is not a database

Related

API receiving undefined data

I'm new to JS and react, but I'm attempting to pass a string to my API which will then run analysis on said string and pass back a sentiment score. However when I pass the data, whilst in my API's console the string appears in the 'body', the API states that the 'Description' is undefined, causing the API to throw an error.
api.js
const express = require('express');
const app = express()
app.use(express.json());
app.post('/', function (req, res) {
console.log('body is:', req.body);
const {description} = req.body;
console.log('Description is:', description);
var Analyzer = require('natural').SentimentAnalyzer;
var stemmer = require('natural').PorterStemmer;
var analyzer = new Analyzer("English", stemmer, "afinn");
const sentiment = analyzer.getSentiment(description.split(' '));
console.log('Sentiment is:', sentiment);
res.json(JSON.stringify({sentiment}))
})
app.listen(3000, () => {
console.log('listening on port 3000');
});
diary.js containing the post function and the api call
async function makePostRequest (diaryText) {
let payload = { Description: diaryText };
let res = await axios.post('http://localhost:3000/', payload);
let data = res.data;
console.log("This is the data returned in the post function:",data);
}
makePostRequest("testText").then(response => {
console.log("Data returned from the function call:", response);
}).then(error => {
console.error(error.response.data);
});
This is the output in the console when the above code is executed:
body is: { Description: 'testText' }
Description is: undefined
TypeError: Cannot read property 'split' of undefined
at /Users/ddavies/Desktop/Desktop Storage/programming/MSc_App/api.js:14:54
at Layer.handle [as handle_request] (/Users/ddavies/Desktop/Desktop Storage/programming/MSc_App/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/ddavies/Desktop/Desktop Storage/programming/MSc_App/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/Users/ddavies/Desktop/Desktop Storage/programming/MSc_App/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/ddavies/Desktop/Desktop Storage/programming/MSc_App/node_modules/express/lib/router/layer.js:95:5)
at /Users/ddavies/Desktop/Desktop Storage/programming/MSc_App/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/Users/ddavies/Desktop/Desktop Storage/programming/MSc_App/node_modules/express/lib/router/index.js:335:12)
at next (/Users/ddavies/Desktop/Desktop Storage/programming/MSc_App/node_modules/express/lib/router/index.js:275:10)
at /Users/ddavies/Desktop/Desktop Storage/programming/MSc_App/node_modules/body-parser/lib/read.js:130:5
at invokeCallback (/Users/ddavies/Desktop/Desktop Storage/programming/MSc_App/node_modules/raw-body/index.js:224:16)
Object key is sensitive, Description =/= description
const {Description} = req.body;

nodejs trying to get remote file to open to user

Wondering what I am doing wrong here. All i want is for the mp3 which I have wired in to be downloaded to the user.
My ideal solution would be able to add a mp3 to the front of this.
const express = require('express');
var fs = require('fs');
request = require('request');
const http = require("http");
const https = require("https");
router.get('/a/:url(*)', (req, res) =>{
res.set({
"Content-Type": "audio/mp3",
// 'Transfer-Encoding': 'chunk',
// 'Content-Disposition': 'attachment'
});
const file = fs.createWriteStream("audio.mp3");
var url = req.params.url.substr(0);
console.log(url);
https.get('https://storage.googleapis.com/ad-system/testfolder/OUTOFAREA.mp3', response => {
response.pipe(file);
});
https.get(url, response => {
response.pipe(file);
});
file.push(res);
});
module.exports = router;
error I am getting is
TypeError: file.push is not a function
at router.get (/root/adstichrplayer/server/routes/podcast.js:131:10)
at Layer.handle [as handle_request] (/root/node_modules/express/lib/router/layer.js:95:5)
at next (/root/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/root/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/root/node_modules/express/lib/router/layer.js:95:5)
at /root/node_modules/express/lib/router/index.js:281:22
at param (/root/node_modules/express/lib/router/index.js:354:14)
at param (/root/node_modules/express/lib/router/index.js:365:14)
at param (/root/node_modules/express/lib/router/index.js:365:14)
at Function.process_params (/root/node_modules/express/lib/router/index.js:410:3)
at next (/root/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/root/node_modules/express/lib/router/index.js:174:3)
at router (/root/node_modules/express/lib/router/index.js:47:12)
at Layer.handle [as handle_request] (/root/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/root/node_modules/express/lib/router/index.js:317:13)
at /root/node_modules/express/lib/router/index.js:284:7
You are trying to use .push on a Writeable stream. Only streams that implement a Readable interface can call .push.
If you don't specifically need to persist the file to disk, there's no reason to create the WriteStream. You can pipe directly to Express' res object:
router.get('/a/:url(*)', (req, res) => {
res.set({
'Content-Type': 'audio/mp3',
// 'Transfer-Encoding': 'chunk',
// 'Content-Disposition': 'attachment'
});
const url = req.params.url.substr(0);
console.log(url);
https.get(url, mp3Response => {
// pipe response from HTTP request to Express res object
mp3Response.pipe(res);
});
});

What to log to debug Error [ERR_HTTP_HEADERS_SENT]?

In an Express controller function, I am running into to this error Error [ERR_HTTP_HEADERS_SENT]. This occurs when I call res.json() if headers have already been set on the res object. However, I don't see place in my function (or middleware) where headers could be set prior to my calling res.json().
To debug the cause of this error, I thought I could add some logging. Prior to calling res.json, I could check if headers had been set and, if so, log some information about who set them.
async function get(req, res) {
...
if (res._header) {
logger.debug(...);
}
res.json(...);
Unfortunately, I don't see anything useful in the res object to log, any message that would indicate why/how the headers were set (or who set them). Any suggestions for what I could log to debug this issue? Or other debugging suggestions?
You can patch res.header res.send res.set to log the stack trace for you. For example this is my main application.
const express = require('express');
const app = express();
const someGoody = require('./stupid-blackbox');
/** patch the res **/
app.use((req, res, next) => {
const _header = res.header.bind(res); // .header and .set is an alias pair
const _send = res.send.bind(res);
res.header = res.set = (field, val) => {
console.trace('.header/.set called', field, val);
console.log('-----');
return _header(field, val);
}
res.send = (body) => {
console.trace('.send called', body);
console.log('-----');
return _send(body);
}
next();
})
// some innocent looking middleware
app.use(someGoody);
// my main routes
app.get('*', (req, res) => {
res.json({url: req.url});
})
app.listen(3000);
And for stupid-blackbox.js:
const express = require('express');
const router = express.Router();
router.use((req, res, next) => {
res.header('X-Crash-You', '1').send(':)');
next();
})
module.exports = router;
When ran, you will get this in the log:
Trace: .header/.set called X-Crash-You 1
at ServerResponse.res.header.res.set (C:\Users\eric_\Desktop\initial\play\index.js:11:13)
at router.use (C:\Users\eric_\Desktop\initial\play\stupid-blackbox.js:6:9)
at Layer.handle [as handle_request] (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:317:13)
at C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\layer.js:95:5)
-----
Trace: .send called :)
at ServerResponse.res.send (C:\Users\eric_\Desktop\initial\play\index.js:17:13)
at router.use (C:\Users\eric_\Desktop\initial\play\stupid-blackbox.js:6:36)
at Layer.handle [as handle_request] (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:317:13)
at C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\layer.js:95:5)
On the second line of each stack trace you can see the stupid-blackbox.js.
On a side note, res.json will not result in error if only res.header or res.set is called, the error is headers has been sent so that means somewhere in the code, res.send is called causing headers to be sent before your actual code.

Expressjs Routes based on an Array of objects

Trying to setup routes based on an array of objects in ExpressJS, but I'm getting an error when attempting to access the route.
The error is this:
TypeError: shares[Symbol.iterator] is not a function
at router
(C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\routes\shares.js:10:18)
at Layer.handle [as handle_request] (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\index.js:317:13)
at C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\index.js:275:10)
at expressInit (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\middleware\init.js:40:5)
at Layer.handle [as handle_request] (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\index.js:317:13)
at C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\index.js:284:7
from code like this:
var router = (shares) => {
for(let share of shares){
shareRouter.route(`/${share.name}`)
.get((req, res) => {
var fileList = [];
fs.readdir(share.location, (err, files) => {
for(let file in files){
fileList.push(file);
shareRouter.route(`/${file}`)
.get((req, res) => {
var filePath = path.join(share.location, file);
res.download(filePath, `${file}`);
});
}
}).then(()=>{
res.render('shareFiles', fileList);
});
});
}
};
shares is defined prior to the router function call. What's supposed to happen is that when the application starts, it looks in the config file, imported earlier, get's the list of folders to share and sets them up based on the name property of the object, then goes through each of the files in the folder to create routes based on their file names, which is then passed into a pug template that provides links to the file routes.

Facebook Messenger API: Can't Get POST Requests

I followed steps which in this page
https://developers.facebook.com/docs/messenger-platform/quickstart
My nodejs codes
app.post('/webhook/', function(req, res) {
messaging_events = req.body.entry[0].messaging;
for (i = 0; i < messaging_events.length; i++) {
event = req.body.entry[0].messaging[i];
sender = event.sender.id;
if (event.message && event.message.text) {
text = event.message.text;
sendTextMessage(sender, "Text received, echo: ");
}
}
res.sendStatus(200);
});
And I get an error like this
TypeError: Cannot read property 'entry' of undefined
at /home/user/public_html/app/testbot/webhook.js:31:30
at Layer.handle [as handle_request] (/home/user/public_html/app/testbot/node_modules/express/lib/router/layer.js:95:5)
at next (/home/user/public_html/app/testbot/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/home/user/public_html/app/testbot/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/user/public_html/app/testbot/node_modules/express/lib/router/layer.js:95:5)
at /home/user/public_html/app/testbot/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/home/user/public_html/app/testbot/node_modules/express/lib/router/index.js:330:12)
at next (/home/user/public_html/app/testbot/node_modules/express/lib/router/index.js:271:10)
at serveStatic (/home/user/public_html/app/testbot/node_modules/express/node_modules/serve-static/index.js:74:16)
at Layer.handle [as handle_request] (/home/user/public_html/app/testbot/node_modules/express/lib/router/layer.js:95:5)
I can't get POST requests which coming from Facebook. How can I solve that?
I was stuck before with the same problem. You need to use the body-parser lib:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var jsonParser = bodyParser.json();
then pass it to the post hook
app.post('/webhook/', jsonParser, function(req, res) {

Resources