Search code examples
node.jsaxiosgoogle-drive-api

return response data from async call


I created this function to get list all my drives from GDrive.

    async getAllDrives(token) {
        let nextPageToken = ""
        let resultArray = []        
        const config= {
            headers: {
                Authorization: `Bearer ${token}`
            }
        };
        const bodyParams = {            
            pageSize: 2,
            fields: 'nextPageToken, drives(id, name)',
            q:`hidden=false`,
        };
        do {
            axios.get(
                `https://www.googleapis.com/drive/v3/drives`,
                config,
                bodyParams,
            ).then(result => {
                nextPageToken = result.data.nextPageToken;  
                resultArray.push(result.data.drives);
                resultArray = resultArray.flat();                
                console.log("result", resultArray);
            }).catch(error => {
                console.log(error);
                //res.send(error);
            });
        }while(nextPageToken);
        resultArray = resultArray.flat();
        resultArray.map(drive => {
            drive.isSharedDrive = true;
        return drive;
        });
        return JSON.stringify(resultArray);
        
    }

When I look in console.log

then(result => {
                nextPageToken = result.data.nextPageToken;  
                resultArray.push(result.data.drives);
                resultArray = resultArray.flat();                
                console.log("result", resultArray);

            })

I have the expected result,

result [
  {
    kind: 'drive#drive',
    id: '**',
    name: ' ★ 🌩'
  },
]

but return JSON.stringify(resultArray); is empty. I found a similar question here, How do I return the response from an asynchronous call? but the answer is not satisfying.


Solution

  • I believe your goal is as follows.

    • You want to retrieve the drive list using axios.
    • Your access token can be used for retrieving the drive list using Drive API.

    Modification points:

    • In order to use nextPageToken in the request, in this case, it is required to run the script with a synchronous process. So, async/await is used. This has already been mentioned in the existing answers.
    • When I saw your script, I thought that the query parameter might be required to be included in the 2nd argument of axios.get().
    • In order to use nextPageToken, it is required to include the property of pageToken. In your script, pageToken is not used. By this, the infinite loop occurs because nextPageToken is continued to be returned.

    When these points are reflected in your script, how about the following modification?

    Modified script:

    let resultArray = [];
    const config = {
      headers: {
        Authorization: `Bearer ${token}`,
      },
      params: {
        pageSize: 2,
        fields: "nextPageToken, drives(id, name)",
        q: `hidden=false`,
        pageToken: "",
      },
    };
    do {
      const { data } = await axios
        .get(`https://www.googleapis.com/drive/v3/drives`, config)
        .catch((error) => {
          if (error.response) {
            console.log(error.response.status);
            console.log(error.response.data);
          }
        });
      if (data.drives.length > 0) {
        resultArray = [...resultArray, ...data.drives];
      }
      nextPageToken = data.nextPageToken;
      config.params.pageToken = nextPageToken;
    } while (nextPageToken);
    resultArray.map((drive) => {
      drive.isSharedDrive = true;
      return drive;
    });
    return JSON.stringify(resultArray);
    

    Testing:

    When this script is run, the following result is obtained.

    [
      {"id":"###","name":"###","isSharedDrive":true},
      {"id":"###","name":"###","isSharedDrive":true},
      ,
      ,
      ,
    ]
    

    Note:

    • From the official document of "Drives: list",

      pageSize: Maximum number of shared drives to return per page. Acceptable values are 1 to 100, inclusive. (Default: 10)

      • So, when pageSize is 100, the number of loops can be reduced. If you want to test the loop using nextPageToken, please reduce the value.

    References: