0

I am having trouble returning a value to an outermost function from an async call. The object is part of a step for the React-Simple-Chatbot and I am attempting to use the validator function. It accepts one value, a string from user input. I need to return either true or a string to the validator to make it work. I cannot figure out how to get my function and/or callback to return the data to the validator.

    let p;
     {
        id: 'productTypes',
        user: true,
        validator: function(value) {
            response(value, this.id, function(answer){
                return p
            })
        },
        trigger: ({value}) => value.toLowerCase() === 'back' ? 'back' : 'productDetails'
    }


    function response(value, id, callback) {
            getData(value, id).then(x => p = x.data).then(x => callback(x))
    }

    function getData(value, id) {
           return axios.get('http://localhost:8085/chatbot', {params: {value: value, func: id }})
    }

I've also attempted to resolve this issue using async/await. The problem with this is that the initial value of p being returned to validate is undefined but subsequent calls to the validate function work. I'm not sure why return p is being run before response(value, this.id).

    {
           id: 'productTypes',
           user: true,
           validator: function(value) {
              response(value, this.id);
              return p;
           },
           trigger: ({value}) => value.toLowerCase() === 'back' ? 'back' : 'productDetails'
    },

    async function response(value, id) {
       let data = await getData(value, id);
       p = data.data;
    }

    function getData(value, id) {
        return axios.get('http://localhost:8085/chatbot', {params: { value: value, func: id }})
    }
  • Are you expecting `p` to be defined at validator function? – guest271314 Jan 21 '18 at 15:04
  • Possible duplicate of [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) – Matt Morgan Jan 21 '18 at 15:04
  • I was expecting p to be set to x.data in the response() function after the promise is resolved. – Jacob Wylie Jan 21 '18 at 15:09
  • @MattMorgan I went through that whole thread but i'm still struggling because of the unique validator function that I'm dealing with. – Jacob Wylie Jan 21 '18 at 15:11
  • I don't know. I can't pass a callback to the validator function. Do you have any suggestions on how to return the data from the async call to the `validator`? * This was a response to a previous questions but it has been deleted. – Jacob Wylie Jan 21 '18 at 15:25
  • The code at Question appears to return expected result https://jsfiddle.net/njo97qgg/. Why do you `return p` from the callback function passed to `validator` function? – guest271314 Jan 21 '18 at 15:30
  • @guest271314 The `validator` requires a value to be returned to it in order to go to next step. If I return `true` it will go to the `trigger` and if I return a `string` it will alert the user that it is not a valid entry. `p` will be returned from `getData()` as a either a `string` or `boolean`. – Jacob Wylie Jan 21 '18 at 15:42
  • I can't figure out how to return the `data` from the `response()` to the outer `validator`. That's why I was attempting to use a callback in the previous entry – Jacob Wylie Jan 21 '18 at 15:55

1 Answers1

0

The async/await pattern does not return a value from response function call and does not await the result of response() call at validator()

let p;

async function validator(value) {
  try {
    await response(value);
    console.log("validator:", {p});
  } catch(err) {
    throw err
  }
  return p;
}

async function response(value, id) {
  try {
    let data = await getData();
    p = data.data;
  } catch(err) {
    throw err
  }
  return p;
}

function getData(value, id) {
  return Promise.resolve({
    data: 123
  })
}

validator()
.then(value => {
  console.log("then:", {p});
  // do `trigger` stuff with p
})
.catch(err => console.error(err));
guest271314
  • 1
  • 15
  • 104
  • 177
  • I really appreciate you helping me out. Unfortunately the `validator` is part of the chatbot API that I am using and did not write myself. I think that's where my problems are stemming from. Your answers would absolutely work though if I could change the validator to handle a promise. API is here [https://lucasbassetti.com.br/react-simple-chatbot/#/docs/steps](https://lucasbassetti.com.br/react-simple-chatbot/#/docs/steps) – Jacob Wylie Jan 21 '18 at 16:10
  • It should be as simple as this but the`validator` is receiving a `promise object`??? `validator: async function(value) { let data = await getData(value, this.id); return data.data; }` – Jacob Wylie Jan 21 '18 at 16:23
  • If `value` is a `Promise` object within your code then you can `await value` before calling `getData()` – guest271314 Jan 21 '18 at 16:38
  • `value` is not a `Promise` object. It is a `string` passed from the user. – Jacob Wylie Jan 21 '18 at 16:48
  • Then what is the issue? Have not tried the library referenced at the Question. – guest271314 Jan 21 '18 at 16:53
  • The problem is that I cannot figure out how to return anything to the `validator`. I can only return a `Promise` or data that has not been resolved by the `Promise` yet. I'm completely lost. It might just be the nature of the API I am using will not cooperate. Any ideas? – Jacob Wylie Jan 21 '18 at 17:26
  • Have not tried the API. Would only be speculating if suggested a pattern outside of the scope of what have tried. Outside of the code at the pattern at Answer not certain how to provide an accurate answer. Have you considered contacting the author of or contributors to the code base to ask them how to properly use their API given your requirement? – guest271314 Jan 21 '18 at 18:06
  • Yeah I don't think it's going to work without modifying the codebase. I tried to dive into in but could really find what I was looking for. I did email the author a bit ago. Thanks again for the help! – Jacob Wylie Jan 21 '18 at 18:11