2

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

user9275416
  • 35
  • 1
  • 6
  • You might want to check this solution and see if it helps: https://stackoverflow.com/a/43547095/3550662 – Keno Feb 15 '19 at 03:48
  • I checked the solution, but I couldn't find anything in the network type related to headers. Also, I have only developed the api, how to add those lines mentioned in the solution in the code in java backend server? – user9275416 Feb 15 '19 at 03:57

3 Answers3

2

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()
}
mix0lydian
  • 400
  • 5
  • 15
  • If i dont do clone, I am getting the following error: "Promise {: SyntaxError: Unexpected end of JSON input" and "Failed to execute 'json' on 'Response': body stream is locked" – user9275416 Feb 15 '19 at 04:05
  • can you please help – user9275416 Feb 15 '19 at 05:14
  • How about ` .then(response => { return response.json() } ).then( myJson => { return JSON.stringify(myJson) } )` Also, can you share what you get if you console.log response, as in response => { console.log(response) } ? – mix0lydian Feb 15 '19 at 06:35
  • I getting the following logs "esponsebody: (...)bodyUsed: trueheaders: Headers {}ok: trueredirected: falsestatus: 200statusText: ""type: "cors"url: "http://localhost:8080/api/profile"__proto__: Response webpack-internal:///./src/services/UserService.js:33 SyntaxError: Unexpected end of JSON input at eval (webpack-internal:///./src/services/UserService.js:28) webpack-internal:///./src/components/WhiteBoard.js:104 undefined webpack-internal:///./src/components/WhiteBoard.js:110 undefined" – user9275416 Feb 15 '19 at 16:11
1

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.

user9275416
  • 35
  • 1
  • 6
0

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.