Node JS app only display the first JSON object. Why? - javascript

I am trying to write a json object in my node application, integrating the Twilio API. When console logging the object all objects are returned properly but when I write it to the document only the first object is written. Why? How should I change the code to see the same written response as in my console log.
var express = require('express');
var app = express();
app.use(express.bodyParser());
app.get('/', function(req, res) {
var accountSid = 'xxx';
var authToken = 'xxx';
var client = require('twilio')(accountSid, authToken);
client.messages.list({
from: "xxx",
to: "xxx"
}, function(err, data) {
data.messages.forEach(function(message) {
console.log(message.body); // THIS WILL DISPLAY ALL OBJECTS
res.json(message.body); // THIS WILL ONLY DISPLAY THE FIRST OBJECT
});
});
});
app.listen(1337);
I am new to Node JS and think this is easy to solve, but I still can’t find the solution.

res.json(...); sends back the response. You are doing that in the first iteration over the array, hence the client only gets the first message.
If you want to extract body from all messages and send all of them back, then do that. Create an array with the data you want and send it back. Example:
res.json(data.messages.map(function(message) {
return message.body;
}));

You can only call res.json once per request. You're calling it multiple times in a loop. The first time you call it, the browser receives the response, and you'll get a headers already sent exceptions (or something like that) for all other res.json calls.

res.json actually does a data conversion to JSON. I'd be willing to bet there is something it is not dealing with, or it's simply screwing it up. If the response from Twilio is already json, you probably don't need to do that. Try res.send, instead, which just returns whatever you got back.

Related

Problem with React making Get request to Node(express)

As the title says, i have a part of my react app that tries to get some data from my database, making a select based on the value I passed to it. So im gonna go ahead and first show the code where i think the problem lies:
So first, this is the function from one of my forms that sends the request to the server, i know code is probably ugly, but i can tell from the console.logs that the parameters im sending are what i intend to send(a string called "licenciaInput"
async handleClickLicencia (event) {
event.preventDefault();
console.log(this.state);
console.log("licenciaInput: "+this.state.licenciaInput);
const datoBuscar = this.state.licenciaInput;
axios.get('http://localhost:3001/atletas/:licencia',this.state)
.then(response =>{
console.log(response)
})
.catch(error =>{
console.log(error)
})
And then, i have this function which is called in that localhost route which attempts to get "licencia", and launch a select in my postgresql db where licencia="whatever", you can see the sentence in the code:
const getAtletasByLicencia = (request, response) => {
const licencia = request.body.licenciaInput;
console.log("Request: "+request);
console.log("what the server gets: "+licencia);
// const licencia = request.licenciaInput;
const sentencia ="SELECT * FROM atleta WHERE licencia ='"+licencia+"'";
pool.query(sentencia, (error, results) =>{
if(error){
throw error
}
response.status(200).json(results.rows)
})
}
As you can see, i have console.logs everywhere, and i still cannot access whatever element i send, because i always get on the server console "undefined" value.
TLDR:How can i access the "licenciaInput" i passed from my client form to my server, i have tried request.body.licenciaInput, request.params.licenciaInput, and request.licenciaInput, but none of those seem to work
I also know i have to treat after that the data i receive from the server, but i need to solve this before looking two steps ahead. Im also really new to React and node/express, so feel free to burn me with good practices im not meeting.Thanks in advance
EDIT: Im also adding this code that i have which shows the route for my method in the server:
app.get('/atletas/:licencia', db.getAtletasByLicencia)
As #Gillespie59 suggested that i should send a POST request, but i dont think i should if im both trying to send a parameter to the server to make a select, and then send the results back to the client
Change your request to:
axios.get(`http://localhost:3001/atletas/${this.state.licenciaInput}`)
...
and your route (if you are using express) should look like this:
app.get('/atletas/:licencia', function (req, res) {
var licencia = req.params.licencia
...
})
As you are using request.body you should send a POST request with axios and add a body.

What does this Node.js REST API app snippet do?

function createData(req, res) {
console.log('trying to store Data.')
console.log('testing log ' + req.body.productID)
app.create_data(req, function (err, response) {
console.log('while returning' + response)
console.log('while returning error is '+err)
if(!err){
var jsonString = {}
jsonString['Result'] = "Success"
res.setHeader('Content-Type', 'application/json')
res.send(JSON.stringify(jsonString))
res.end()
}
else{
var jsonString = {}
jsonString['Error'] = err.description
res.setHeader('Content-Type', 'application/json')
res.send(JSON.stringify(jsonString))
res.end()
}
})
}
I've seen the following code for creating data in a REST API example. I can't understand a few things about it, can anyone please explain the overall purpose of this snippet?
What is jsonString['Result'] = "Success" doing, since we have initialized with an empty string?
These is a GET API, where is my code getting data from the text fields?
What does app mean in this Node.js snippet?
Why are we giving the same name that we already gave, like so: app.app.create_data?
This code snippet will create a JSON response to some API route.
This line assigns the string value "Success" to the jsonString object under the 'Result' key. It's a way to store key-value pairs in a JavaScript Object.
This snippet doesn't send anything more, than just what the jsonString object holds, which is either "Result" with the "Success" message or "Error" with a description. It will be converted to JSON and will be sent as a response:res.send(JSON.stringify(jsonString)).
Generally 'app' is an instance of some HTTP server in Node.js
It's just a structuring/naming practice, this can be highly different from project-to-project.
To get started with Node.js apps, check out these links:
Learn Node.js in 1 hour YouTube video
Gettings started with Node.js apps blog series
Creating a simple REST API tutorial blog entry with Express.js

Confused about how to get req.body

I cannot seem to get the body data shown on my server. I am actually trying to get this in post/put/fetch calls, but to try to fix the problem, i've boiled it down to a simple .get, and it still won't appear. Can anyone see why the body isn't showing on the server? I'm unable to get anything done in more complicated called due to this (like get the body of the req, but sticking to this simple example for now.)
This code is a fully working and sends data, just cant seem to access the body on the server.
server.js
const express = require('express');
const app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
const port = process.env.PORT || 8000;
const Cat = require('./Cat');
const Dog = require('./Dog');
app.route('/animals')
.get(function (req, res) {
console.log(req.body, 'req.body log'); //this returns {}
res.send({ Cat, Dog });
})
app.listen(port, () => console.log(`Listening on port ${port}`));
In react, if I call the following callApi() function, console.log shows the body data just fine on the front end, and the data can be used on the page.
client call
callApi = async () => {
const response = await fetch('/animals');
const body = await response.json();
console.log(body) //shows all the data just fine!
if (response.status !== 200) throw Error(body.message);
return body;
};
Using node 9 and express 4.
I think you're confusing the request and response objects. But aside from that, I'll explain where/how to get data passed in from GET and POST/PUT requests.
When a GET request is made, you can pass data to the server via query params (i.e. /animals?type=cat). These parameters will be available already parsed in an object called req.query.
When a POST or PUT request is made, and you've applied the body parsing middleware (which you have done), the JSON will be available as a parsed object under req.body.
In your example, you have made a GET request, and have no provided any query string parameters. So req.body will return an empty object, as will req.query.
Your client call shows data because you've sent data back in the response via res.send(). This is totally unrelated to why req.body is an empty object in your case.
Try using fetch('/animals?type=cat') in your client call. Then, you will see that req.query returns { type: 'cat' }.

Attempting to send object from client to server (AngularJS $http.post)

I'm attempting to store an object that my user clicks on in my server so that when the page changes, all the information from that object can be displayed fully in a profile page.
I'm unfamiliar with Angular $http but I've tried to write a call that will POST to the server, unfortunately when I scan through the req object in VScode I can't find where the object I sent is contained, so I can send it on to my function.
Controller function:
$scope.storeProfile = function(child){
$http.post('/storeTempProfile', child)
.then(function(response) {
window.location.href = 'DemoPage.html';
});
}
server.js:
app.post('/storeTempProfile', function (req, res) {
profileStorage.storeProfile(req);
});
does my app.post look right? And what property of req do I need to use the dot operator on to access my object? I can't seem to find the object data anywhere in req and that makes me thing there's something wrong with how I wrote app.post
It looks like you are using express. So in that case, you want to access the object on req.body, but this will require you use body-parser. The example on their homepage:
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// create application/json parser
var jsonParser = bodyParser.json()
// POST /api/users gets JSON bodies
app.post('/api/users', jsonParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
// create user in req.body
})
You will notice in this example that they pass the json parser into the route itself. This is only necessary if you want to have different parsers for different routes. Usually you just want to set it to all routes, which you can do by using app.use(bodyParser.json()).

Hide an API key (in an environment variable perhaps?) when using Angular

I'm running a small Angular application with a Node/Express backend.
In one of my Angular factories (i.e. on the client side) I make a $http request to Github to return user info. However, a Github-generated key (which is meant to be kept secret) is required to do this.
I know I can't use process.env.XYZ on the client side. I'm wondering how I could keep this api key a secret? Do I have to make the request on the back end instead? If so, how do I transfer the returned Github data to the front end?
Sorry if this seems simplistic but I am a relative novice, so any clear responses with code examples would be much appreciated. Thank you
Unfortunately you have to proxy the request on your backend to keep the key secret. (I am assuming that you need some user data that is unavailable via an unauthenticated request like https://api.github.com/users/rsp?callback=foo because otherwise you wouldn't need to use API keys in the first place - but you didn't say specifically what you need to do so it is just my guess).
What you can do is something like this: In your backend you can add a new route for your frontend just for getting the info. It can do whatever you need - using or not any secret API keys, verify the request, process the response before returning to your client etc.
Example:
var app = require('express')();
app.get('/github-user/:user', function (req, res) {
getUser(req.params.user, function (err, data) {
if (err) res.json({error: "Some error"});
else res.json(data);
});
});
function getUser(user, callback) {
// a stub function that should do something more
if (!user) callback("Error");
else callback(null, {user:user, name:"The user "+user});
}
app.listen(3000, function () {
console.log('Listening on port 3000');
});
In this example you can get the user info at:
http://localhost:3000/github-user/abc
The function getUser should make an actual request to GitHub and before you call it you can change if that is really your frontend that is making the request e.g. by cheching the "Referer" header or other things, validate the input etc.
Now, if you only need a public info then you may be able to use a public JSON-P API like this - an example using jQuery to make things simple:
var user = prompt("User name:");
var req = $.getJSON('https://api.github.com/users/'+user);
req.then(function (data) {
console.log(data);
});
See DEMO

Categories