Node GET by ID API - node.js

I have follow the instructions to create a NODE API here.
I'm trying to have a few endpoints with a NODE app to serve data to my React UI.
The database is mongodb where I have a collection for 'stores'.
I have 2 GET calls:
One to retrieve all stores
One to retrieve a store by ID
Node app.js:
app.get('/viewstores', (request, response) => {
storesCollection.find({}).toArray((error, result) => {
if (error) {
return response.status(500).send(error);
}
response.send(result);
});
});
app.get("/viewstores/:id", (request, response) => {
storesCollection.findOne({ "_id": new ObjectId(request.params.id) }, (error, result) => {
if(error) {
return response.status(500).send(error);
}
response.send(result);
});
});
I make my API calls from axios in React.
If I make a call to the first API to retrieve all stores, there no problem at all, but if I try to make the API call by ID, I still get all stores from the first API.
It seems that I am not able to target the GET by ID api.
React app
React.useEffect(() => {
axios.get('http://localhost:5000/viewstores', {
params: { _id: params.storesid}
})
.then(({data}) => {
console.log("DATA ==> ", data)
})
.catch(error => console.log("ERROR API GET ==> ", error))
}, [])
MongoDB store sample:
_id: ObjectId("12345")
businessname:"ABC"
businessaddress:"address abc 1"
Any idea why when I try to call the GET by ID I always get back the whole collection?
Thanks in advance.
Joe.

Assume params.storesid is 12345,
your current React code sends requests to http://localhost:5000/viewstores?_id=12345, and the route /viewstores is reached. To reach the /viewstores/:id route, the URL should be something likes http://localhost:5000/viewstores/12345 then Express will capture the 12345 part in the URL to request.params.id. You can try the code below:
React.useEffect(() => {
axios.get(`http://localhost:5000/viewstores/${params.storesid}`)
.then(({data}) => {
console.log("DATA ==> ", data)
})
.catch(error => console.log("ERROR API GET ==> ", error))
}, [])
You can read about Express route parameters in the official document.

Related

axios get res.data = null

I've had a blockage since last night and I still don't understand, let me explain.
I use React, Mongo DB, and NodeJs, and axios for my API calls
I created a route to retrieve the info of a user, when I test the route with PostMan, I have the user info so everything works as it should, only when I make the api call from my front, my res.data returns "null", so I think it's coming from my api call, but I can't find what's wrong.
I am attaching some screenshot, thank you in advance:
API call :
function Post() {
axios({
method: "get", url: "http://localhost:4000/api/auth", credentials: true,
params: {
userId: "62f045f5253a960077a8ff3f"
}
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
}
Function back getOneUser:
exports.getOneUser = (req, res, next) => {
userModel.findOne({_id: req.params.userId}).select('-password -email')
.then(post => res.status(200).json(post))
.catch(error => res.status(404).json({error}))
}
In express, use req.query instead of req.params.
This post might clarify the differences between them

Node JS GET API's not working with new data

I am using Node JS and MYSQL. When I add new data to my project, it writes to the database. Then when I want to GET this data with another API, it doesn't come. When I try again after about a minute, it comes on. However, right after I send a request via Swagger, data comes from the outside (Postman or Panel) on my request again.
My simple Controller.
exports.GetAll = (req, res, next) => {
ThisModel.GetAllSQL()
.then((response) => {
res.status(200).json(response[0]);
}).catch((error) => {
res.status(400).send();
console.log('Senaryo listesi çekilirken bir hata meydana geldi: ' + error);
})
}
.then((response) => {
res.status(200).json(response[0]);
})
Judging from the line above, it looks like you're getting a list/array of data, but only returning the first item in the list response[0].
Maybe this is what you're looking for:
.then((response) => {
res.status(200).json(response);
})

AngularJs $http request stays pending and does not return value from the database

I am currently writing a route which allows me to recieve information from a stored procudre I have in a database. I have written a request in AngularJS and a route in NodeJS but I am just recieving a pending request in the chrome Network developer window. I can see that the console.log in the NodeJs app has the data I require so it has retrieved it but there is nothing coming back in any of the console logs in the the AngularJS app.
Here is the code for the both the angularJS app and the Node App:
AnglaurJS:
checkForReplenishmentEmptyTrolley = async () => {
LIBRIS.extensions.openLoadingModal();
console.log('in checkForReplenishmentEmptyTrolley');
try {
const varPromise = await $http.get(`${LIBRIS.config.stockService}stockMovement/checkForUnattachedTrolley`)
.then((response) => {
console.log(response);
// Request completed successfully
}, (error) => {
// Request error
console.log(error);
});
console.log(varPromise.data);
// 1. check that there are no ghost replenish - lines 1-15
console.log('in try/catch');
console.log('promise', varPromise);
} catch (error) {
console.log(error);
}
},
NodeJS code:
app.get(`${ROUTE}/attachTrolley`, async function(req, res){
const newRequest = await DB.newRequest();
console.log('we have made it to the route');
try {
console.log('we have made it to the Try/Catch route');
newRequest.input();
const record = await newRequest.execute('dbo.usp_STK_CheckForUnattachedTrolley');
res.json(record)
console.log(record, 'record');
} catch (err){
handleError(res, err);
console.log(err);
}
});
The problem is that you are doing a .then on a awaited promises and not returning anything from that. You have two choice here
Either return response from then so when you try to access the value here console.log(varPromise.data); it works.
Or remove the .then alltogather as it is not required because you are awaiting it any ways.
Basically just do this
checkForReplenishmentEmptyTrolley = async () => {
LIBRIS.extensions.openLoadingModal();
console.log("in checkForReplenishmentEmptyTrolley");
try {
const varPromise = await $http.get(`${LIBRIS.config.stockService}stockMovement/checkForUnattachedTrolley`);
console.log(varPromise.data);
// 1. check that there are no ghost replenish - lines 1-15
console.log("in try/catch");
console.log("promise", varPromise);
} catch (error) {
console.log(error);
}
};
Hope this fixes your issue.
Solved it! I had no return statement in my route!

how to fetch data after successful authentification with node, express and react (componentDidMount error)

I'm working on a Node-express-react project where I'm calling the Google Analytics reporting API to display some data on the client-side. Right now I have:
my back-end and my front-end on two separate localhosts
A Google Sign-in Button on the front-end redirecting to the back-end to run the OAuth 2.0 authentication process
I'm calling the ga reporting API once I have the token.
Everything is working well so far. Now I'd like to pass the response from the API call to the client-side (react). I have the following component:
componentDidMount() {
// Pick whatever host/port your server is listening on
fetch('http://localhost:5000/getData')
.then(res => { // <-- The `results` response object from your backend
// fetch handles errors a little unusually
if (!res.ok) {
throw res;
}
// Convert serialized response into json
return res.json()
}).then(data => {
// setState triggers re-render
this.setState({loading: false, data});
}).catch(err => {
// Handle any errors
console.error(err);
this.setState({loading: false, error: true});
});
}
Here is my API call on the server-side
router.get('/getData', function(req, res) {
var token = req.query.token;
request('https://www.googleapis.com/analytics/v3/management/accounts?access_token=' + token, function (error, response, body) {
if(error){
console.log(error);
}else{
console.log(JSON.parse(body))
let views = []
JSON.parse(body).items.forEach(view => {
views.push({
name: view.webPropertyId + ' - ' + view.name + ' (' + view.websiteUrl + ')',
id: view.id
})
})
console.log(views)
res.send(views);
}
});
})
The issue is that the componentDidMount() is being called before I click the Google login button which is running into an error because data from the API are not available (since no authentication has been done yet).
Which logic I should follow to have my data being fetch only once the login has been successful?
Thanks.

Client side can't fetch server response

The Problem
I deployed a create-react-app webapp to aws ec2. It's used to display data from a database and send data to it. I use ExpressJS, CORS and MySQL.
With the following code i fetch the corresponding URL and the server.js sends back the database content. Until here, everything works fine.
getBets = _ => {
fetch("http://ec2***.amazonaws.com
.then(response => response.json())
.then(response => this.setState({bets: response.data}))
.catch(err => console.error(err))
};
The problem begins when sending data to the database with the following code:
addBet = _ => {
const { bet } = this.state;
fetch(`http://ec2***.amazonaws.com/bets/add?name=${bet.person_name}&bet=${bet.time_bet}`)
.then(response => response.json())
.then(this.getBets)
.catch(err => console.error(err))
};
On click the addBet-function populates the db, but in chrome I following error:
GET http://ec2***.amazonaws.com/bets/add?name=Peter%20Pan5&bet=10:17%205 net::ERR_EMPTY_RESPONSE
and
TypeError: Failed to fetch
Regarding chrome dev-tools, the first error corresponds to the fetch in the addBet function and the second error to the catch part.
On the server side I've the following code for processing the fetch:
app.get("/bets/add", (req, res) => {
const {name, bet} = req.query;
const INSERT_BET = `INSERT INTO bets (name, bet, timestamp) VALUES("${name}", "${bet}", CURTIME())`;
connection.query(INSERT_BET, (err, res) => {
if (err) {
return res.send(err);
}
else {
return res.send("succesfully added your bet");
}
})
});
I want to mention, that the res paramter in the app.get part is unused. That tells me my IDE.
After a lot of hours digging deeper in the topics of expressJS and the fetch api, I guess, that the app.get part doesn't send a response to the server. But the fetch need some response.
My Question
How do I have to change the code in the app.get part to send a proper response back to the server?
AND
Am I right with my guess?
In MYSQL when you do an insert query you get back err,results and fields in the callback function like this:
connection.query('INSERT INTO posts SET ?', {title: 'test'}, function (error,
results, fields) {
if (error) throw error;
console.log(results.insertId);
});
You have used the parameter res for result and then you have used res.send() which now corresponds to that res parameter in the callback function and not the res object.Rewrite it like this:
app.get("/bets/add", (req, res) => {
const {name, bet} = req.query;
const INSERT_BET = `INSERT INTO bets (name, bet, timestamp) VALUES(?,?,?)`;
connection.query(INSERT_BET,[name,bet,CURTIME()] ,(err, result) => {
if (err) {
return res.send(err);
}
else {
return res.send("succesfully added your bet");
}
})
});
I have also used prepared statement in place of normal sql queries. These are used to prevent sql injections. I hope it will work now.

Resources