Reputation: 311
I am trying to work with some async functions but my code, for example this.saveAsCSV(lists,"lists.csv"); seems to continue before the function completes. This is not exactly what I am doing but it is the shortened version that shows my issue. console.log(lists) has the correct data but I assume it is evaluated after the call
public render(): void {
(async () => {
await this.GetListsBySiteID("6a368204-0534-4ffb-8014-157524ca9d50").then(lists => {
console.log(lists);
this.saveAsCSV(lists,"lists.csv");
});
})();
}
async GetListsBySiteID(id:string):Promise<string[]>
{
let lists1:string[] = [];
await pnp.sp.site.openWebById(id).then(result =>
{
result.web.lists.get().then(lists =>
{
lists.forEach(list => {
lists1.push(list.Title);
});
})
});
return lists;
}
How do I correct this?
Upvotes: 0
Views: 643
Reputation: 73906
Here is a full async/await solution to this issue. Using await
on result.web.lists.get()
will wait for the process to finish first and then when resolved, finally giving you the correct lists
public render(): void {
(async() => {
const lists = await this.GetListsBySiteID("6a368204-0534-4ffb-8014-157524ca9d50")
console.log(lists);
this.saveAsCSV(lists, "lists.csv");
})();
}
async GetListsBySiteID(id:string):Promise<string[]> {
let lists1: string[] = [];
const result = await pnp.sp.site.openWebById(id)
const lists = await result.web.lists.get()
lists1 = lists.map(x => x.Title);
return lists1;
}
Please note that in your post, you are returning lists
at the end inside GetListsBySiteID
and that variable is not defined inside the function. So, if you want to return lists1
instead simply replace return lists;
with return lists1;
.
Upvotes: 1
Reputation: 519
The code is not tested, but this is the idea:
GetListsBySiteID
functionlists
value populatedGetListsBySiteID(id:string):Promise<string[]> {
return new Promise((resolve, reject) => {
try {
let lists:string[] = [];
pnp.sp.site.openWebById(id).then(result =>
{
result.web.lists.get().then(lists =>
{
lists.forEach(list => {
lists.push(list.Title);
});
resolve(lists);
})
});
} catch (ex) {
reject(ex);
}
);
}
Upvotes: 1
Reputation: 8515
It's because in your GetListsBySiteID()
function you have this code:
await pnp.sp.site.openWebById(id).then(result =>
{
result.web.lists.get().then(lists =>
{
lists.forEach(list => {
lists.push(list.Title);
});
})
});
So what happens here is JavaScript is await
ing for the pnp.sp.site.openWebById(id)
Promise to complete before continuing. You have attached the .then()
callback so it's being await
ed too. Now the problem is in your .then()
callback:
You are calling result.web.lists.get().then()
but this Promise is not being await
ed for. The solution is to add return
keyword, like this:
await pnp.sp.site.openWebById(id).then(result =>
{
return result.web.lists.get().then(lists => // <-- here I added return
{
lists.forEach(list => {
lists.push(list.Title);
});
})
});
So now the await
will cause JavaScript to wait for the nested Promise also.
Upvotes: 1