Reactnative: undefined response when fetiching data from localhost symfony API - javascript

I have an app build with reactnative, it is running on my local pc, and i would like to fetch and display data from a local symfony api that i have running.
The reactnative code is fetching from my local pc ip, and the symfony port/route:
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: [],
}
}
componentDidMount() {
return fetch('http://10.161.170.86:8000/api/hardwarePlacement')
.then((response) => {
console.log(response.ok);
})
.then((response) => response.json())
.then((responseJson) => {
console.log(response.ok);
this.setState({
isLoading: false,
dataSource: responseJson.hardwarePlacements,
})
})
.catch((error) => {
console.log(error)
});
}
And the json data i get from my symfony API looks like so, when i get it from postman or go directly through the browser:
[{"id":1,"name":"Bryggers","createdDate":{"date":"2023-02-08 15:14:12.000000","timezone_type":3,"timezone":"Europe\/Berlin"},"editedDate":{"date":"2023-02-14 13:57:07.000000","timezone_type":3,"timezone":"Europe\/Berlin"}},{"id":2,"name":"Stue","createdDate":{"date":"2023-02-08 21:52:46.000000","timezone_type":3,"timezone":"Europe\/Berlin"},"editedDate":{"date":"2023-02-08 21:52:46.000000","timezone_type":3,"timezone":"Europe\/Berlin"}},{"id":3,"name":"Stue","createdDate":{"date":"2023-02-14 13:57:10.000000","timezone_type":3,"timezone":"Europe\/Berlin"},"editedDate":{"date":"2023-02-14 13:57:10.000000","timezone_type":3,"timezone":"Europe\/Berlin"}}]
The error i get in my terminal is:
[TypeError: undefined is not an object (evaluating 'response.json')]
If i try with fetching data from an public URL instead, it works fine, it is only from getching data from localhost url, it fails.

Return from the first then
.then((response) => {
console.log(response.ok);
return response
})
.then((response) => response.json())

Related

REACT: Fetch returns response as not ok but Network tab shows data

I am new to react and when I am trying to fetch the json response into UI I am getting error, even though the network tab shows the json response.
Please help me in resolving this.
Code-
useEffect(() => {
console.log('Inside UseEffect');
fetch(`http://localhost:8080/api/hello`
,{ mode: 'no-cors', method: 'GET' })
.then((response) => {
if(!response.ok) throw new Error(`This is an HTTP error: The status is ${response.status}`);
else return response.json();
})
.then((json) => {
this.setState({
teamList: json});
console.log(this.state.teamList);
})
.catch(err => console.log(err));
}, [] )
Network tab response looks like-
[{"id":1,"title":"Team1"},{"id":2,"title":"Team2"},{"id":3,"title":"Team3"},{"id":4,"title":"Team4"},{"id":5,"title":"Team5"},{"id":6,"title":"Team6"}]
And the Console tab has below output-
Inside UseEffect
Error: This is an HTTP error: The status is 0
Instead of
if(!response.ok) throw new Error(`This is an HTTP error: The status is ${response.status}`);
else return response.json();
in the then anonymous function do console.log({response})
You can then see in the console what the object looks like and interrupt how to extract the data from it.
response.ok is most likely undefined

axios.get request returning GET,HEAD as response

I'm using React, Redux, Node, Axios and working on adding pagination to my request using mongoose-paginate-v2. My axios.get looks like this:
export const getUsers = (page) => {
return (dispatch, getState) => {
axios.get(`${USERS_ENDPOINT}/${page}`,
{
headers: {
Authorization: `${USERS_TOKEN}`,
"token": cookies.get('token')
}
})
.then(async response => {
dispatch({
type: GET_USERS,
payload: response.data.list,
page: page
});
}).catch(e => { console.log(e); return e })
}
}
and my rest-api function looks like this:
app.get('/allusers/:page', auth, (req,res)=>{
console.log('req',req)
let log={}
Object.assign(log,{header:req.headers,body:req.body,query:req.query,params:req.params})
request(uri,USERS_FILTER,{token: req.header('token'), page:req.params.page
}).then(result => {
res.status(200).send(result);
}).catch(error => {
logger.error('log error',{error:error})
if(error.response.errors[0].message==='Error: 401'){
res.status(401).send('Not Permitted');
}else{
res.status(500).end(); // Or other error handling
}
});
logger.info('users request log',log)
});
My backend is working properly when i test it with postman, but when i use my UI to send the request I get status 200 and GET, HEAD as response, when using postman I get a tab with my users.
This is a screenshot of my request:
PS: i'm using:
node v12.6.0
react v16.6.3
express v4.16.3
I resolved this using the cors package https://www.npmjs.com/package/cors

Get response headers object in redux with React.js

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>').

Not getting data in fetch even if the status is 200 in react

I am having below problem with the fetch function:
React code:
componentDidMount() {
this.userService.getLoggedInUser()
.then(user => {
this.setState({user: user});
console.log(this.state.user);
})
}
This the course service file code:
getLoggedInUser(){
const USER_API_URL = API_URL + "/api/profile";
return fetch(USER_API_URL, {
headers : {
'Content-Type' : 'application/json'
},
method : "POST"
}).then(response => response.clone()).then(data => {
console.log(data);
return data;
}).catch(function (err) {
console.log(err)
});
}
I am just trying to get the logged in user from the server. While using postman to do the same, I am getting the output as expected.
Server Code:
#PostMapping("/api/loggedInUser")
public Faculty getLoggedInUser(HttpSession session){
return (Faculty)session.getAttribute("currentUser");
}
Class in the server is defined as:
#RestController
#CrossOrigin(origins = "http://localhost:3000", allowCredentials ="true")
public class UserService {
In postman, I am getting the below output:
{
"id": 100,
"username": "bird",
"password": "bird",
"firstName": "Alice",
"lastName": "Kathie"
}
But in the react app, I am getting in the console as:
Response {type: "cors", url: "http://localhost:8080/api/profile", redirected: false, status: 200, ok: true, …}
But there is no data body to return or parse. I am not sure what I am doing wrong here. I have tried changing the then method in the fetch to various types, like response.clone().json() etc, but, in most cases, I am getting the output as "promise rejected, unexpected end of json input".
How can I solve this problem?
Thanks
Looks like the error is in how you are handling your response:
}).then(response => response.clone()).then(data => {
The data in your second .then() isn't returning the fetch response, it is returning the details of the fetch itself. In .then(response => you probably want to do:
.then(response => {
return response.json()
}
It isn't clear what you are trying to do with response.clone(), as this typically creates a clone of the response for use with caching or something -- what are you trying to do with the clone?
If you're using it in a cache function maybe you could:
.then(response => {
someCacheFunction(response.clone())
return response.json()
}
or if you are setting it to a pre-defined variable for some use:
var responseClone;
... // code omitted
.then(response => {
responseClone = response.clone()
return response.json()
}
Found the answer. Main problem was with the cookies. While fetching, we need to make sure following is set:
getLoggedInUser = () => {
const USER_API_URL = API_URL + "/api/profile";
return fetch(USER_API_URL, {
headers : {
'Content-Type' : 'application/json'
},
method : "POST",
'credentials': 'include'
}).then(response => {
console.log(response);
return response.json()
}).catch(function (err) {
console.log(err)
});
}
"credentials":"include" is necessary so that the browser is accepting cookies and the same cookie is used to retrieve the data from the server.
I've found that fetch is unreliable. Try axios instead. See https://axios-http.com/docs/intro for info, or run npm i axios and add it to your project with import axios from 'axios', then call axios.get(YOUR_URL).
Probably too old a thread by now, but maybe this will help a little.

Why response.data is undefined?

I am fetching data using an API in react native. When fetched data in console, its successfully getting data. But while using the code below, the album array is showing undefined.
state = { albums: [] };
componentWillMount() {
//fetch('https://ws.audioscrobbler.com/2.0/?method=chart.gettoptracks&api_key=881262b246e1d3f2abda8771b1a25fe3&format=json')
fetch('https://rallycoding.herokuapp.com/api/music_albums')
.then(response => this.setState({ albums: response.data }));
}
I am getting console logs like this
{albums: Array(0)}
{albums: undefined}
Why this is undefined?
A Response object has no data property. You access the body of the response by calling the text, json, blob, or arrayBuffer methods and consuming the promise they return.
For instance, if you're receiving JSON:
fetch('https://rallycoding.herokuapp.com/api/music_albums')
.then(response => response.json())
.then(data => this.setState({ albums: data }));
Live Example:
fetch('https://rallycoding.herokuapp.com/api/music_albums')
.then(response => response.json())
.then(data => {
console.log(data);
});
Or we could call the parameter albums and use shorthand property notation:
fetch('https://rallycoding.herokuapp.com/api/music_albums')
.then(response => response.json())
.then(albums => this.setState({ albums }));

Categories