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))
}
Related
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(...);
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 hope you can help me.
I'm trying to get a response from an API and use that information in another file.
I have 3 files:
api.jsx
import axios from 'axios';
export const api = (url, data) => {
const { path, method } = url;
let result ={};
axios({
method: method,
url: path,
data: data
})
.then(res => {
result = res.data;
console.log(res.data);
})
.catch(err => console.error(err));
return result;
};
url.jsx
export const URL = {
users:
{
getAllUsers: { path:'/users', method: 'post'},
login: { path:'/login', method: 'post'},
register: { path:'/register', method: 'post'},
version: { path:'/', method: 'get'},
}
}
app.js (within the render)
const data = {
email: 'hello#world.com',
password: '12345',
};
let result = api(URL.users.login, data);
console.log(result);
In the api file i get the proper response but in the react component no. I am aware that It's a problem of sync as i get first the console of app.jsx and later on the console of the api.jsx but i would like to respect the current structure or make something similar.
Any idea how to fix this without many changes?
PS. sorry about the mess. I tried to highlight all the code but for some reason it is not working fine.
You want to return a Promise in api.jsx
api.jsx
export const api = (url, data) => {
const { path, method } = url
return axios({ // the axios call returns a promise because of its .then; you can just return it
method: method,
url: path,
data: data
})
.then(res => {
return res.data;
})
.catch(err => {
console.error(err)
})
}
Using redux in React.js I get the most starred repositories in the last 30 days, now I wanna use the pagination that github api provides but to do so I have to use the headers in the response, how can I do that, how can I change my code to get the headers from the response, this is the function that gets the response:
import getDate from './getDate';
export function fetchRepos() {
return function(dispatch) {
dispatch({
type: "FETCH_REPOS_REQUEST",
});
return fetch(
"https://api.github.com/search/repositories?q=created:>" +
getDate() +
"&sort=stars&order=desc",
)
.then(response => response.json().then(body => ({response, body})))
.then(({response, body}) => {
if (!response.ok) {
dispatch({
type: "FETCH_REPOS_FAILURE",
error: body.error,
});
} else {
dispatch({
type: "FETCH_REPOS_SUCCESS",
repos: body.items,
});
}
});
};
}
Please help, thank you!
I like to assemble a response object that includes the headers as an object for fetch calls like so:
fetch('https://jsonplaceholder.typicode.com/users')
.then(res => (res.headers.get('content-type').includes('json') ? res.json() : res.text())
.then(data => ({
headers: [...res.headers].reduce((acc, header) => {
return {...acc, [header[0]]: header[1]};
}, {}),
status: res.status,
data: data,
}))
.then(response => console.log(response)));
in your case you could then simply get the headers with response.headers in the last .then().
but technically you can access the headers with res.headers.get('<header.name>').
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.