17

So I've created a component that shoots off post requests with props that I provide.

Although I'm familiar with Async await I for some reason can't seem to get this to return the actual value of the fulfilled promise and instead just get pending.

I've tried wrapping with more functions as I understand the promise is not being resolved.

I feel like I'm missing something.

A sample of my code below

export default class PostController extends React.Component {
constructor(props) {
    super(props)
}
Wrapper = (body) => {
    try{
        let x = this.Send(body);
        return x;
        console.log(x)
    }catch(e){console.log(e)}
}
Send = async (body) => {
        try{
            let data = await this.Post(body);
            return data;
        }catch(e){console.warn(e)}       
}
Post = async (body) => {
    try{
        const options = {
            method: 'POST',
            uri: 'XXXXXXXXXXXXXXXXXXXX',
            body: body
        }
        const data = await rp(options);
        return data; 
    }catch(e){console.warn(e)}
}
render(props) {
    let jsonBody = JSON.stringify(this.props.data)
    const returnData = this.Wrapper(jsonBody)
    console.log(returnData)

        return(
            <div>
                 {(!this.props.data.pw) ? 'Retrieved Password: ' + returnData.message : 'Generated PassWord!:' + returnData.message }
            </div>
        )
    }

}

2
  • Can you show what rp(options) is, and why it awaits something?... Commented Mar 1, 2019 at 1:15
  • request promise, its a library that wraps the regular request library in a promise. Commented Mar 1, 2019 at 1:30

2 Answers 2

12

I think you need more about async/await in JS.

An async function always return a promise. So x in Wrapper is a promise. Because you don't use await/async.

It should be like this.

async Wrapper = (body) => {
    try{
        let x = await this.Send(body); // <-- missing await here
        return x;
    }catch(e){console.log(e)}
}

But then, the code in render doesn't work. because this.Wrapper() now returns a promise. -> returnData is a promise. And the render method can't be async function :)

render(props) {
    //... 
    const returnData = this.Wrapper(jsonBody) // <-- returnData here is a promise.
    //...

So to make things work.

You have to use state. Call the this.Wrapper in componentDidMount or componentDidUpdate. For example:

constructor() {
    // ...
    this.state = { returnData: null }
}
async componentDidMount() {
   const returnData = await this.Post(...); // Using await to get the result of async func
   this.setState({ returnData });
}

async Post(body) {
  try{
    const options = {
      method: 'POST',
      uri: 'XXXXXXXXXXXXXXXXXXXX',
      body: body
    }
    return rp(options); // define await then return is unnecessary 
  }catch(e){console.warn(e)}
}

render() {
     const { returnData } = this.state;
    // ... Do the rest

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

6 Comments

Excellent! Didn't realize could use componentdidmount like that! I have a lot to learn!
@Scottt: if the answer is what you need. go mark it as correct answer!
But won't this unnecessarily fetch posts for each mount? Which will result in very inefficient code.
Unexpected reserved word 'await'. I am using it in async componentDidMount() strange!
@Suisse maybe you're using old version that does not support async await?
|
0

I believe you should try marking Wrapper function as async and awaiting on it before console logging returnData. Also await on Send() inside Wrapper.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.