Hello I created a form allowing me to choose which database table I want to observe. I then want to make a query based on the selected data but it seems that the format or my way of doing it does not seem good.
Here is my fetch function:
temp_select: 'temperature'
async exportData(){
const data_select = encodeURIComponent(this.temp_select);
const url = `http://192.168.1.51:3000/api/v1/export/${data_select}`;
fetch(url)
.then(res => res.text())
.then((result) => {
console.log(typeof(data_select));
const data = JSON.parse(result);
console.log(data);
})
.catch((error) => {
console.log(error)
});
},
and here is my query function
async function exportDatabase(req, res){
const data_selected = req.params.data_select;
return db.any('SELECT $1 FROM tag_7z8eq73', [data_selected])
.then(rows => {
res.json(rows)
})
.catch(error => {
console.log(error)
});
}
the database is loaded but here is what I observe
It works correctly in this form:
async function exportDatabase(req, res){
return db.any('SELECT temperature FROM tag_7z8eq73')
.then(rows => {
res.json(rows)
})
.catch(error => {
console.log(error)
}); }
I'm working with node.js and vue.js
Can someone enlighten me?
edit : #Quentin Thank you for your answer you help me understand how the GET request works. Here is my problem solved :
fetch function :
async exportData(){
const data_select = encodeURIComponent(this.temp_select);
const url = `http://192.168.1.51:3000/api/v1/export/${data_select}`;
fetch(url)
.then(res => res.text())
.then((result) => {
console.log(typeof(data_select));
const data = JSON.parse(result);
console.log(data);
})
.catch((error) => {
console.log(error)
});
},
Query function:
async function exportDatabase(req, res){
const data_selected = req.params.data_select;
return db.any('SELECT ' + data_selected + ' FROM tag_7z8eq73')
.then(rows => {
res.json(rows)
})
.catch(error => {
console.log(error)
}); }
my route :
router.get('/export/:data_select', db.exportDatabase);
method: 'GET',
You are making a GET request
headers: {
'Content-Type': 'application/json',
},
This claims that the request body is JSON.
GET requests cannot have a request body, so this cannot be true.
(Technically they can, but really shouldn't, but fetch won't let you give a GET request a body).
Remove this header.
params: JSON.stringify({
data_select: this.temp_select,
}),
fetch does not have a params option, so this is nonsense. Remove it.
async function exportDatabase(req, res){
return db.any('SELECT $1 FROM tag_7z8eq73', [req.params.data_select])
Assuming you are using Express, look at the definition of params:
This property is an object containing properties mapped to the named route “parameters”. For example, if you have the route /user/:name, then the “name” property is available as req.params.name. This object defaults to {}.
Which means you need to define data_select when you define the route:
app.get('/api/v1/export/:data_select', exportData);
And then put the value in the URL when you make the request:
const data_select = encodeURIComponent(this.temp_select);
const url = `http://192.168.1.51:3000/api/v1/export/${data_select}`;
fetch(url).then(...);
Related
I am building a user website, where the admin should be able to delete users.
My project is build using Azure SQL database.
I have in my controllers file, come up with an endpoint deleteUser
deleteUser
const deleteUser = (req, res) => {
sql.connect(config, function (err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
const { id } = req.query
request.query(
`DELETE FROM users where User_ID = '${id}'`,
function (err, recordset) {
if (err) {
console.log(err);
} else if (!id) {
res.json("Please provide an ID")
} else {
res.json(`User with ID: ${id} has been deleted!`)
}
}
);
});
};
I am then trying to make a call to this endpoint using fetch and EJS.
My code in EJS script tag
<script>
document.getElementById('deleteUserBtn').addEventListener('submit', (e) => {
e.preventDefault();
fetch('http://localhost:3000/deleteUser', {
method:'DELETE',
headers: {
"Content-Type": "application/json",
},
body: null
})
.then((response) => console.log(response))
.catch((e) => {
console.log(e)
})
})
</script>
I console log the response, so the route must be good, but it seems as it doesn't parse the ID into the fetch. What is the right way to approach this?
Thanks in advance!
Solution
I have come up with follow solution - which is not the best, but works.
document.getElementById('deleteUserBtn').addEventListener('submit', (e) => {
e.preventDefault();
// delete user using fetch
const id = document.getElementById('userId').textContent
fetch(`http://localhost:3000/deleteUser?id=${id}`, {
method:'DELETE',
headers: {
"Content-Type": "application/json",
},
body: null
})
.then((response) => console.log(response))
.catch((e) => {
console.log(e)
})
})
Thanks for the contribution!
Should the id not be in the URL of the fetch request? You are asking for the id from the request params, so it should probably be appended to the path like
const id = wherever your id comes from;
fetch('http://localhost:3000/deleteUser?id=${id}...'
You'll need to get the user's id in your button method as well, but would need more of your code to see where that comes from.
Usually using an ID for deletion is best approach
fetch('http://localhost:3000/deleteUser/:id...'
However, you can pass id in anyway in body, params, query or even headers)
I am trying to send the param name in the Cloud Function managed by Firebase using POST method, I've read quite a few documentation, and no matter what I try it always returns undefined. Also is it safe to use this for sensitive data?
Client-Side
fetch(`https://<<APP-NAME>>.cloudfunctions.net/addCardForExistingCustomer`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
JSON.stringify(body: {'name': 'Name'})
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(err => console.error(err));
Server-side (Firebase Cloud-Functions)
exports.addCardForExistingCustomer = functions.https.onRequest(async (request, response) => {
let name = await request.body.name
response.json({
response: `${name}`
})
})
Oh once again I have those Promise.all blues:( I have a function that makes an array of fetch call's from provided urls and then we want to retrieve data via a Promise.all and return array of reponses or better yet just return the promise to calling function. . The problem is this results in error w/console showing:
There was problem retrieving data. TypeError: r.json is not a function
The code for the function is :
const getLeagueLeaders = (url, params) => {
// First let's create the array of url's
let queryURLs = [];
params.forEach((param) => {
queryURLs.push(
fetch(`${url}${new URLSearchParams(param)}`, {
method: "get",
headers: {
Authorization:
"Basic ==",
},
}).then((res) => res.json())
);
});
return (
Promise.all(queryURLs)
// map array of responses into an array of response.json() to read their content
.then((responses) => responses.map((r) => r.json()))
.catch((err) => {
console.error("There was problem retrieving data.", err);
})
);
};
module.exports = getLeagueLeaders;
And in Vue component
mounted: async function () {
const leagueLeadersResponseArray = await getLeagueLeaders(
this.fetchBaseUrl,
this.params
);
this.qbLeaders =
leagueLeadersResponseArray[0].cumulativeplayerstats.playerstatsentry;
Obviously leagueLeadersResponseArray is undefined. I researched .json() and dont see how I am using it incorrectly. At first i thought I needed a Promise.all wrapper for the responses.map((r) => r.json()) but that did no good either. I looked at this link but I am not using fetch as he is. Any guidance much appreciated....
Updated working code for anybody else:
// ---------- src/js/modules/ ------------------ //
/* jshint ignore:start */
// Make function to retrieve League Leaders in a Category
const getLeagueLeaders = (url, params) => {
// First let's create the array of url's
let queryURLs = [];
params.forEach((param) => {
queryURLs.push(
fetch(`${url}${new URLSearchParams(param)}`, {
method: "get",
headers: {
Authorization:
"Basic ==",
},
}).then((res) => res.json())
);
});
return Promise.all(queryURLs).catch((err) => {
console.error("There was problem retrieving data.", err);
});
};
module.exports = getLeagueLeaders;
Your template string is around the entire fetch when it should only be in the argument to fetch:
params.forEach((param) => {
queryURLs.push(fetch(`${url}${new URLSearchParams(param)}`, {
method: "get",
headers: {
Authorization:
"Basic *****==",
}
}));
});
Then, you have a .then(data => {return data}), which doesn't do anything since the return returns from the then callback, not the function. You should instead return the promise that Promise.all gives you:
return Promise.all(queryURLs)
// map array of responses into an array of response.json() to read their content
.then((responses) => responses.map((r) => r.json())) // Get error There was problem retrieving data. TypeError: r.json is not a function
.catch((err) => {
console.error("There was problem retrieving data.", err);
});
I have a PHP file. When I send category:'true' with the POST method in HTML JS, it gives me back text which I echo in PHP but with React Native it sends me an object instead. How can I solve this?
This is my code:
return fetch('http://709957ef.ngrok.io/follower/get%20json.php',{
method:'POST',
body:JSON.stringfy({
category:'true'
})
})
.then((response) => response.text())
.then((responsetxt) => {
alert(responsetxt)
})
.catch((error) => {
console.error(error);
});
}
change your code to and add async to our function.
componentDidMount = async () => {
const response = await fetch('http://709957ef.ngrok.io/follower/get%20json.php',{
method:'POST',
body:JSON.stringify({
category:'true'
})
})
this.setState({
data: response.text(),
}, () => console.log('PHP DATA: ', this.state.data))
}
I am making an app where I receive data from an API. Once I get this data I want to make another call to the same API with the endpoint that I got from the first call.
fetch(req)
.then((response)=>(
response.json()
)).then((json)=>{
console.log(json)
json.meals.map((obj)=>{
let url = `https://spoonacular-recipe-food-nutrition-v1.p.mashape.com/recipes/${obj.id}/information`
let req = new Request(url,{
method: 'GET',
headers: header
})
fetch(req)
.then((response)=>(
response.json()
)).then((json)=>{
console.log(json);
this.setState((prevState)=>{
recipe: prevState.recipe.push(json)
})
})
})
this.setState(()=>{
return{
data: json
}
})
})
I am making two fetch requests here but the problem is the data from the first response is output after second fetch request. Also the state: data gets set before state: recipe and the components render with the data from state: data.
render(){
return(
<div className="my-container">
<EnterCalorie getData={this.getData}/>
<MealData data={this.state.data} recipe={this.state.recipe}/>
</div>
)
}
How can i make sure both get passed down at the same time?
In line 3 return return response.json() instead of nothing (undefined).
Update:
const toJson = response => response.json()
fetch(req)
.then(toJson)
.then(json => {
this.setState(() => {
return {
data: json
}
})
return json
})
.then((json) => {
console.log(json)
const promises = json.meals.map((obj) => {
let url = `https://spoonacular-recipe-food-nutrition-v1.p.mashape.com/recipes/${obj.id}/information`
let req = new Request(url, {
method: 'GET',
headers: header
})
return fetch(req)
.then(toJson)
.then((json) => {
console.log(json);
this.setState((prevState) => ({
recipe: prevState.recipe.push(json)
}))
})
})
return Promise.all(promises)
})
.then(() => {
console.log('job done')
})
You need to map your array into promises. Then use Promise.all to wait for them the get resolved.
There was parenthesis missing from:
this.setState((prevState)=>{
recipe: prevState.recipe.push(json)
})
A sidenote, this whole stuff should be refactored. You're not going to get far with this code style / code complexity.
fetch(req) // req no1
.then((response)=>(
response.json()
)).then((json)=>{
console.log(json)
json.meals.map((obj)=>{
let url = `https://spoonacular-recipe-food-nutrition-v1.p.mashape.com/recipes/${obj.id}/information`
let req = new Request(url,{
method: 'GET',
headers: header
})
fetch(req) // req no 1 called again
.then((response)=>(
response.json()
)).then((json1)=>{
console.log(json1);
this.setState((prevState)=>{
recipe: prevState.recipe.push(json1)
})
this.setState(()=>{
return{
data: json
})
})
})
})
})
I think you are calling api with same req parameters again in the second fetch call
This is a callback hell, please look for Promise races, and check the all() promise method.