0

I have just started learning JavaScript and am building an application using React. I am struggling with an issue and would appreciate your help. I did come across similar questions but wasn't convinced with the answers and they didnt help me. Please find my issue below . I am hiding the real name of the variables , components .

myService.js

export const findThisById = async Id=> {
  const response = await fetch(`${URL}/${Id}`);
  const json = await response.json();
  return json;
};

myContainer.js // This is the parent component which has many chil component

        .......
     import {findThisById} from "../myService"

            findThis= async Id=> {
            const xyz= await findThisById(Id);  
            return xyz;

         <Component1 findThis = {this.findThis}/>
        ......

Component1.js

const Component1 = ({findThis}) => (

<Component2 findThis = {findThis} id = {Id} // Id is being passed successfully 
   />

)

Component2.js

    class Component2 extends React.Component {
      constructor(props) {
        super(props);
        console.log("Inside Constructor");
        const something = this.props.findThis(this.props.id); 
        // course.then(data => console.log(data) // This works, i get the right data
        )
        console.log(something ); // Using this i get Promise state pending    
      }

 // I need to use this value "something" inside a <h1></h1>

}

I have ommited all exports/imports but they work correctly The network tab in the console also make a 200 request and the response sub tab shows the correct values. Should i use .then when i call the function findThis? Why? I am using await for fetch and its response. Please help me. Struggl

reactdontact
  • 53
  • 1
  • 10
  • `async/await` is just syntax sugar for promises. You can't ignore the async flow when calling an async function down the tree, it's still just a Promise, so either await it as well, or simply use a `then`. – Emile Bergeron Feb 17 '20 at 05:00
  • Thank you. I refereed this website : https://javascript.info/async-await When you scroll down the function showAvatar() is being called without await . Can you please help me understand this – reactdontact Feb 17 '20 at 05:02
  • 2
    Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Emile Bergeron Feb 17 '20 at 05:02
  • 3
    You either need to await the call: `const something = await this.props.findThis(this.props.id);` or use `.then`, you're right in the sense that you're waiting _inside_ that function, but _outside_ it you still need to handle the async nature of it. The place where it's called is still just a regular synchronous context – Jayce444 Feb 17 '20 at 05:03
  • 1
    All `async` functions return a promise. To get the resolved value from any `async` function, you have to either use `.then()` or `await` on the returned promise. Always. No way around it. When you `return something` inside an `async` function, that just tells the interpreter to make that value be the resolved value of the promise that the `async` function already returned or is about to return. – jfriend00 Feb 17 '20 at 05:06
  • Makes sense, Thanks everyone. – reactdontact Feb 17 '20 at 05:11

1 Answers1

3

As mentioned in one of the comments async / await is just syntactic sugar for promises, so generally speaking you can either await or .then the result of findThis. That said, since you are calling this inside of a constructor function you won't be able to use await since the constructor isn't an async function.

One way to get the result of the Promise to render in your component would be to set the result in the component state and then render from the state. As mentioned by @Emile Bergeron in a follow up comment, you probably don't want to call setState in your constructor but instead in componentDidMount. This is to avoid calling setState on a potentially unmounted component.

class Component2 extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      searchResult: ''
    } 
  }

  componentDidMount() {
    this.props.findThis(this.props.id).then(searchResult => {
      this.setState({
        searchResult
      })
    });  
  }

  render() {
    return <div>{this.state.searchResult}</div>
  }
}
bingles
  • 11,582
  • 10
  • 82
  • 93