Getting undefined value when trying to access json data - javascript

I am fetching some json data from the api http://www.omdbapi.com/?t=batman&y=&plot=full&r=js.
Printing out text in console giving me correct data. However when I am trying to access any of its properties its giving me undefined.
var url = "http://www.omdbapi.com/?t=batman&y=&plot=full&r=json";
request.get(url, function(err, res){
if (this.isMounted()) {
this.setState({data : res.text});
}
}.bind(this));
If I try below one it's printing correct data
console.log(this.state.data);
But if I try below it's giving me undefined.
console.log(this.state.data.Title);

Remove res.text property.Also try to log res in the console and see if its an object
var url = "http://www.omdbapi.com/?t=batman&y=&plot=full&r=json";
request.get(url, function(err, res){
if (this.isMounted()) {
this.setState({data : res});
}
}.bind(this));

Related

Res.send sends an empty object, even though console.log shows it isn't empty?

I am trying to use the google-sheets api with express and don't have much experience with javascript. I'm attempting to use pass a json object from express to react, but it seems that whenever I finally send the object, it just renders as empty on the frontend?
I've tried using res.body/res.data, but the object doesn't seem to have either. I've also tried to put as many awaits as I can everywhere to make sure the object is loaded in before sending, but nothing seems to do the trick. If I use res.json or res.send with just the response object, I get a circular structure converting to JSON error. Here is the code I'm working with.
async function docShit() {
// Initialize the sheet - doc ID is the long id in the sheets URL
const doc = new GoogleSpreadsheet(
"--SPREADSHEET ID--"
);
// Initialize Auth - see https://theoephraim.github.io/node-google-spreadsheet/#/getting-started/authentication
await doc.useServiceAccountAuth({
// env var values are copied from service account credentials generated by google
// see "Authentication" section in docs for more info
client_email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL,
private_key: process.env.GOOGLE_PRIVATE_KEY,
});
await doc.loadInfo(); // loads document properties and worksheets
const sheet = doc.sheetsByTitle[--WORKSHEET TITLE--];
const rows = await sheet.getRows(); // can pass in { limit, offset }
return rows;
}
app.get("/home", async (req, res) => {
try {
await docShit()
.then((response) => {
res.send(Promise.resolve(response)); //console log shows the object, but res.send just sends nothing??
})
.catch((err) => console.log(err));
} catch (err) {
console.error(err.message);
}
});
There is no res.send at all in your code. Also, you use await and .then together, but I consider them alternatives. Try the following:
app.get("/home", async (req, res, next) => {
try {
var response = await docShit();
console.log(response);
/* If response is circular, decide which parts of it you want to send.
The following is just an example. */
res.json(response.map(function(row) {
return {id: row.id, cells: row.cells.map(function(cell) {
return {id: cell.id, value: cell.value};
};
})};
} catch (err) {
console.error(err.message);
next(err);
}
});

Unable to get redis key-value pair using Node.js (ERR_HTTP_HEADERS_SENT)

Trying to fetch key-value pair from my localhost redis client using Node.js.
If I include the res.json() inside the function/for loop, I get HTTP_HEADER error for sending response more than once.
If I define it outside the function/loop, I get an empty array.
Error:
_http_outgoing.js:485
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
Below is the code for app.js
router.get('/route1', function(req, res)
{
var valarr=[];
client.keys('*', function(err, keys) {
console.log(keys);
for(var i=0;i<keys.length;i++){
client.get(keys[i], function (error, value) {
if (err) return console.log(err);
console.log(value);
valarr.push(value);
// res.json({result1:keys, result2:valarr});
//I get ERR_HTTP_HEADERS_SENT if res.json() is defined here
});
}
console.log(valarr); //Empty
res.json({result1:keys, result2:valarr});
//Returns an empty array (valarr)
});
});
You getting (ERR_HTTP_HEADERS_SENT), because you are not checking if value variable have value or not. Just add condition using IF to check value variable. If value will have value then only it will be added in valarr
array and will send updated valarr array as response.
SOLUTION :
router.get('/route1', function(req, res)
{
var valarr=[];
client.keys('*', function(err, keys) {
console.log(keys);
for(var i=0;i<keys.length;i++){
client.get(keys[i], function (error, value) {
if (err) return console.log(err);
if(value){
console.log(value);
valarr.push(value);
res.json({result1:keys, result2:valarr});
}
});
}
console.log(valarr); //Empty
res.json({result1:keys, result2:valarr});
//Returns an empty array (valarr)
});
});

Loop through array of Mongoose data

I'm trying to fetch an array of data from Mongoose, loop through the array and add an object to Three.js scene for each item in array.
When I try to render the scene in the browser I'm getting an error saying:
"client_world.js:37 Uncaught (in promise) TypeError: data is not iterable at getData"
However when I console log the data in the get request querying the database, it prints all of the data entries as an array, sp they must be iterable.
I think maybe the data is not arriving to the javascript file.
Here is the code to get the data from the db:
const indexVR = (req, res) => {
Upload.find({})
// .populate('Upload')
.exec(function (err, docs) {
if (err) res.send(err)
// docs.toString()
res.json(docs)
console.log(docs)
})
};
this function is in the following get req:
router.get('/indexvr', FileCtrl.indexVR);
This is the code snippet from the js file:
getData()
async function getData() {
const response = await fetch('/api/indexvr');
const data = await response.json;
console.log(data)
for (item of data) {
try {
scene.add( cube );
} catch (e) {
console.error(e)
}
}
}
nothing in logging to the console in the getData function, however the browser is reading some kind of empty json object.
.. Does anyone know what I'm doing wrong?
Your issue may be as simple as calling the .json method as opposed to referencing it.
Referring to this document: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch .json is a method of the response object returned from fetch.
Try using const data = await response.json();

Socket.io-emit in callback gives SyntaxError: Unexpected end of JSON input

So I'm exporting a callback-function in a module like this:
(function() {
let request = require("request");
module.exports = function GithubApi(url, callback) {
let options = {
uri: url,
headers: {
"User-Agent": "Me",
"Content-Type": "application/x-www-form-urlencoded"
}
};
request(options, function(err, body) {
let context = {
issues: JSON.parse(body.body).map(function(issue) {
return {
title: issue.title,
comments: issue.comments,
};
})
};
callback(context) // The callback
});
};
}());
And this callback works perfectly fine when I'm using it in my GET-request with express.js:
app.get("/", (req, res) => {
let url = "some url";
GithubApi(url, (data) => {
res.render("../some-views", data);
});
});
But when I add a socket-emit, the callback-function returns SyntaxError: Unexpected end of JSON input
app.get("/", (req, res) => {
let url = "some url";
GithubApi(url, (data) => {
io.socket.emit("update", {message: data}); // adding this
res.render("../some-views", data);
});
});
Can't understand why the socket would interfere with the request and return an error with JSON. Can anybody help?
The probablem must be caused by the fact that body.body doesn't contain a valid JSON string.
When you run code like this:
JSON.parse(body.body)
you should always use try/catch because JSON.parse throws exceptions on bad JSON.
See those answers for more details:
Calling a JSON API with Node.js
Node JS ignores undefined check
How to extract inner string from the array string
Node server crashes in parsing JSON
So the problem was with the io.sockets.emit("update", {message: data});. For some reason, that interfered with the request(still don't know why tough). I guess it has something to do with the socket broadcasting to all channels, and that causes some kind of error, read something about it here.
So I changed the call to the callback-function to this:
GithubApi(orgs, repo, token, (data) => {
io.of("/").emit("update", {message: data}); // This line made it work
res.render("../views/home", data);
});

restful API using node not returning anything

In my server.js I do:-
app.post('/app/getSingleOrderDetail', function(req,res,next){
orderController.getSingleOrderDetail(req.body.order_id);
})
then in models
exports.getSingleOrderDetail = function(order_id, res, res) {
Orders.find({'_id':order_id}).exec(function(err,result){
console.log('result: '+result) //it's ok!!
res.json(result);
});
};
I'm expecting the result with this $http call in angularjs
$http({
url: '/app/getSingleOrderDetail',
method: "POST",
data: {'order_id' : id}
}).then(function(response){
console.log(response.data)
vm.sales_detail = response.data;
}).catch(function(response) {
alert('Error!');
console.log(response);
});
Everything is passed correctly but I just couldn't get the data back to client side in angularjs.
In getSingleOrderDetail you're expecting the arguments (order_id, res, res), When you're invoking the function though, you're only passing in a value to the first argument, order_id and nothing for res. Also, you've defined res twice which is going to cause an issue in your code when trying to access res.
You should fix up those issues like so
Route
app.post('/app/getSingleOrderDetail', orderController.getSingleOrderDetail);
Model
exports.getSingleOrderDetail = function(req, res) {
let order_id = req.body.order_id;
Orders.find({'_id': order_id}).exec(function(err,result) {
if (err) return res.status(500).send(err);
console.log('result: ' + result); //it's ok!!
return res.status(200).json(result);
});
};
Just a side note, from the looks of your route name, this wouldn't be considered RESTful, it would be more of an RPC (Remote Procedure Call) style API.

Categories