Home > OS >  Wait for all recursive api calls to finish and process the result
Wait for all recursive api calls to finish and process the result

Time:11-25

I have a function that has a api call in it. The function gets all folder, subfolders with in folders and File paths using recursion. The idea is to store the all the paths in an array to be later processed to create a tree view JSON. Through this method I am able to get all the paths.

public componentDidMount(){
let upperArray: any[] = [];
this.getFiles("/sites/spfxsite/TestLib", upperArray);
// Process the upperArray once last recursion call is completed.
}

public getFiles(folderUrl: string, upperArray: any[]): any {
sp.web.getFolderByServerRelativeUrl(folderUrl)
  .expand("Folders, Files").get().then((r: any) => {
    r.Files.forEach(item => {
      if (item.ServerRelativeUrl.indexOf("Forms") == -1) {
        console.log(item.ServerRelativeUrl);
        upperArray.push(item.ServerRelativeUrl);
      }
    })
    r.Folders.forEach(item => {
      if (item.ServerRelativeUrl.indexOf("Forms") == -1) {
        console.log(item.ServerRelativeUrl);
        upperArray.push(item.ServerRelativeUrl);
        this.getFiles(item.ServerRelativeUrl, upperArray);
      }
    })
  });
}

The issue is that the code moves to process the upperArray before all the recursive calls are finished. How can I wait for all recursive call to finish and process the upperArray in the end.

A bit about the api call: the call uses PNP Js to get all files and folders from SharePoint Library.

I am using React Js and Typescript for development. File extension is .tsx

CodePudding user response:

It looks to me like there's promises involved? If that's the case, you could try to define a temporary array and push to that, pass it on to another then or finally and then push it to upperArray.

Might work?

mdn

CodePudding user response:

That's because you're calling what is essentially an asynchronous function, but calling it synchronously. So your function call returns before the async bits have even started.

Use async/await. It makes you code cleaner and simpler, something like this:

public async componentDidMount() {
  let upperArray: any[] = [];
  await this.getFiles("/sites/spfxsite/TestLib", upperArray);
  // Process the upperArray once last recursion call is completed.
}

public async getFiles(folderUrl: string, upperArray: any[]): any {
  const res = await sp.web
    .getFolderByServerRelativeUrl(folderUrl)
    .expand("Folders, Files")
    .get();
  const isWanted = item => item.ServerRelativeUrl.indexOf("Forms") == -1;

  for (const file of res.Files.filter(isWanted)) {
    upperArray.push(file.ServerRelativeUrl);
  }

  for (const folder of res.Folders.filter(isWanted)) {
    upperArray.push(folder.ServerRelativeUrl);
    this.getFiles(folder.ServerRelativeUrl, upperArray);
  }

}
  • Related