0

My objective is to do these functions one by one when the previous is finished and activate some kind of loading meanwhile these functions are in progress.

Instead there is visible, that all functions ignores await a process after this loadable component.

Why this is happening and how I can reach that function will start when the previous is done? I am trying to do all of this in componentDidMount(). I have @babel dependencies v7+.

In console is visible, that this async/await function is ignored and the loadableComponent is finished before all function starts.

edit: More reproducible example:

"base_coponent" (defined LoadableComponent which extends React.Component)

export class LoadableComponent extends React.Component {
constructor(props) {
    super(props)
    this.state = {
        loading: true,
        loading_counter: 0
    }
}

activateLoad() {
    let i = this.state.loading_counter
    console.log("setting loading", this.state)
    this.setState({loading: true, loading_counter: i + 1 }, function () {
        console.log("after setting loading counter", this.state)
    })
}

deactivateLoad() {
    let i = this.state.loading_counter
    console.log("in deactivateLoad", this.state)
    if (i == 1) {
        console.log("disabling loading")
        this.setState({ loading: false, loading_counter: 0 })
    } else if (i <= 0) {
        console.log("disabling loading")
        this.setState({ loading: false, loading_counter: 0 })
    } else {
        console.log("setting loading")
        this.setState({ loading: true, loading_counter: i - 1 })
    }

}

user action (from where is exported function getAppuser() and rest of functions)

export function getAppuser(appuser) {
return dispatch => { 
    let url = `${config.server}/fs/data/getAppuser/${appuser}`
    axios.get(url).then((data) => {

        dispatch({type: list.user.GET_APPUSER, data: data.data})            
    }).catch(
        err => {
            console.error(err)
        }
    )
}

"index" (the palce of happening. specifially class Content extends LoadableComponent)

1) defined async loadable

async loadable(b, e = (err) => { console.error(err) }) {
    this.activateLoad()
    try {
        await b()
        this.deactivateLoad()
    } catch (err) {
        this.deactivateLoad()
        e(err)
    }
}

2) componentDidMount()

this.loadable(async () => {

      try {

        console.log("start of Loadable")

        await this.props.dispatch(getAppuser(appuserID))
        await this.props.dispatch(getSettings(appuserID))
        await this.props.dispatch(getAppuserRank(period))

        console.log("in the end of Loadable")
      } catch (err) {

        console.log(err)
      }

  })

package.json just some of all depenedencies and devdependencies, which i found as important by some other tutorials in my case

"devDependencies": {
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.9.6",
"@babel/polyfill": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@babel/runtime": "^7.9.6",
"babel-loader": "^8.0.0",
"babel-plugin-add-module-exports": "^0.3.2",
"babel-plugin-react-html-attrs": "2.0.0",

console log when i apply the logic from Bergeron topic - the difference between this console log and console log i put in top is, that the log "after setting loading counter" is no more visible, which is not right by me. enter image description here

trying 1) tried to create: new Promise in user-action. But in this case, Iam getting an error, that Actions must be plain objects. Use custom middleware for async actions.

export function getAppuser(appuser) {
return new Promise(function (resolve, reject) {
    return dispatch => { 
        let url = `${config.server}/fs/data/getAppuser/${appuser}`
        axios.get(url).then((data) => {

            dispatch({type: list.user.GET_APPUSER, data: data.data})            
        }).catch(
            err => {
                console.error(err)
            }
        )
    }
})
  • Does this answer your question? [Why calling react setState method doesn't mutate the state immediately?](https://stackoverflow.com/questions/30782948/why-calling-react-setstate-method-doesnt-mutate-the-state-immediately) – Emile Bergeron May 18 '20 at 19:55
  • not really. When i apply the logic in this topic, nothing changes. But iam not sure if a did everything same as the example. You sure, that this logic works on dispatch same as setstate? Iam a quite beginner so maybe iam saying shi*s. Sorry :( – Martin Zelenka May 18 '20 at 20:42
  • you've put a console log right after a `setState` in your `activateLoad` which sure will never log the updated values. [Quentin's answer](https://stackoverflow.com/a/61877561/1218980) is also a right, but it's a guess from your question, which is missing a [mcve]. – Emile Bergeron May 18 '20 at 20:48
  • ok, i tried to apply the example in activateLoad, but now, nothing shows. I mean there is no more visible log "after setting loading counter". I will add more detailed example of my issue in next comment. Thank you – Martin Zelenka May 18 '20 at 20:55
  • From your answer, I see that you've failed to implement the `setState` callback correctly. Right now, the callback looks like it's not even a parameter of `setState`, which would explain your last comment, it's never called because it's never passed correctly. – Emile Bergeron May 18 '20 at 21:19
  • oh.. Correct. Now it is ok. But it wont fixed my problem of "awaitng" functions. From Quentin answer i tried to rewrite exproted function to promise, but there is an error i describe in trying 1). – Martin Zelenka May 19 '20 at 05:17

1 Answers1

1

Probably dispatch doesn't return a promise. If it does, it can't resolve based on the value passed to it (since all the values passed to dispatch are undefined).

You can only usefully await a promise.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • ok, if i got it right, only promise can be "awaited". I tried changed exported function which i call in this.props.dispatch(getAppuser... to return new Promise(dispatch => {axios... It seems, that function is now called in right order, but no one is proccesed because there is an error "Actions muset be plain objects. Use custom middleware for async actions" – Martin Zelenka May 18 '20 at 20:07