0

I am trying to fetch a simple JSON element from express.js. I am trying have React assign it to a state variable on the front end. I am using this code to do so:

componentDidMount() {
    fetch("/user")
    .then(response => response.json())
    .then(result => this.setState({myUser:result}))
}

But when I run typeof myUser after this setState command, it says string instead of object. I've tried using JSON.parse(), etc. But either I get an error or it continues to assign the data as a string rather than JSON. What sort of syntax do I need to use in this fetch-then context to coerce the data assignment to be JSON?

I have read this link:

With this code:

componentDidMount(){
  fetch('https://abx.com/data/tool.json').then(response =>{
    if (!response.ok) throw Error('Response not ok')

    return response.json(); // This is built in JSON.parse wrapped as a Promise
  }).then(json => {
    this.setState({"sections" : json});
  }).catch(err =>{
    console.log(err);
  });
}

But it doesn't solve the problem. I ran this code directly in my application verbatim. When I run typeof on the variable, it says string instead of object. I looked at other posts on Stack Overflow, but I did not see a solution to this.

3
  • This is not normal, you are doing fetch right and second example is a different structure from yours. What is the output when you look in your second .then method like that instead of setting the state? .then( result => console.log( typeof result ) ); or what is the output of just this: .then( console.log ); Commented Jun 9, 2018 at 1:21
  • Also, after setting the state right like this can you see anything with React Dev Tools? Is it possible that you are getting an error respond? Commented Jun 9, 2018 at 1:22
  • Could you share what your render function looks like? This is a good site for that: codesandbox.io/s/new this.setState is asynchronous, so you could be trying to access a change before its dispatch by react behind the scenes. The pattern I usually follow inside of a component is if (state not ready) { render Loading } then when the next state is triggered render what you want. Commented Jun 9, 2018 at 1:58

1 Answer 1

0

I figured out what was going wrong (after many hours of experimenting): On the server side, I was creating a "homegrown" JSON object using string and variable concatenation. I also tried creating the JSON object by doing this:

var str = "name:" + name + ", department:" + department var user = {str};

Both of these were not working in subtle ways... despite trying different types of gadgetry on the client side, I couldn't get React to interpret the data as a JSON object. But then I had an idea to construct the JSON on the server side (in Express.js) like this:

var user = {}; user["name"] = name; user["department"] = department;

That immediately cleared things up on the server side and the client side. When using setState() in React, it now sets the value as an object (which was the goal all along).

I think this can be useful to others... if React doesn't seem to understand the JSON, perhaps it is being sent from the server in a subtly incorrect format.

Sign up to request clarification or add additional context in comments.

2 Comments

Why are you creating your object like that? At the end it looks like something {str: "name:foo, department:moo"} and this is not what you intend. You fixed it somehow but in the first place why don't you define you user like that: const user = { name: name, department: department, } So, I think this is not a React issue. After all your so called JSON is not an actual JSON. It seems that you are trying to setup an object here.
Correct. The JSON was not being constructed properly on the server, and that was the unknown/unexpected reason React was having difficulty assigning it as an object via setState(). This solved it: var user = {}; user["name"] = name; user["department"] = department; I'll have to also explore the syntax you indicate: const user = { name: name, department: department, } .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.