How to make an array accessible under different functions in Javascript?

83 views Asked by At

Im using React Table to fetch data from an API and populating it in the table. I make an API call and get the data. Once I have the data, I extract a field which contains the email ids and then make an array(emailList). Now I want to use the data in emailList as the part of the body in the POST API call afterwards. So in the code below, the recipients parameter under the POST call should contain the data of emailList. The emailList is declared as an empty array globally in the render method. With my current setup, I get an undefined error due to scoping issues. How to make the value accessible under the POST call? I have gone through few scoping StackOverflow answers and tried but didn't get the result.

    columns: [
    {
filterable: false,
Header: 'Action',
accessor: 'action',
Cell: (e) => (
  <button
      onClick={() => {
        axios.get(URL, {
          headers: {
            'content-type': 'application/json',
            'Name' : user.Name,
          },
          responseType: 'json',
        })
        .then((response) => {
          let responseData = response.data.data;
          function getEmailList(input, email) {
            var output = [];
            for (var i=0;i<input.length; ++i)
              output.push(input[i][email]);
            return output;
          }
          emailList = getEmailList(responseData, "email");

          function fetchEmail() {
            this.emailList = getEmailList(responseData, "email");
          }  

        });

        //console.log(new fetchEmail().emailList);
        //Unable to get the value of emailList here
        axios({
          method: 'post',
          url: URL2,
          headers: {
            'content-type': 'application/json',
            'Name' : user.Name,
          },
          data: {
            "topic": "product",
            "message": {
               "sender": "[email protected]",
               //For illustration I have hardcoded the email arrays for recipients
               "recipients": ["[email protected]", "[email protected]"],
              "data": {
                        "text": "refresh"
              },
           "attachment": null,
           "type": "",
            },
          },
        })
1

There are 1 answers

0
Jonas Wilms On BEST ANSWER

I think this is rather a race problem ( aka you try to Post before the emails arrived at the browser), so you need to change your code that the post awaits the get. That can be easily done with promises:

 {
   //a cache
   let promise;

   //a promising getter:
   function getEmails (){
     //if cached return
     if( promise ) return promise;
     //else await the request
     return promise = axios.get(URL,{/*options*/}).then( response => response.data.data.map(obj => obj.email));
   }
 }

So now we can do:

 getEmails().then( console.log);
 getEmails().then( console.log);

Both calls will return the same promise, so theres just one request, but we can call it multiple times. For example, we can call it before doing the POST:

 getEmails().then( emails => {
  axios({
   //...
   data:{
    message:{
      recipients: emails
    }
  }
 });
});