SPFx Extension: wait for fetching data before rendering header
-
06-02-2021 - |
Вопрос
I am currently developing a SPFx Extension (Application Customizer). I am relatively new to TypeScript (C# developer) and I can't find my error.
I have the following onInit method:
@override
public onInit(): Promise<void> {
this._getUserInformation(); // gets user information via the graph api
this._getLinks(); // gets information of a SharePoint List
this._renderPlaceHolders(); // renders my header with information taken from the information I took at the last two methods
}
But _renderPlaceHolders() gets called before the other two methods. All the time. Why? I tried async/await and Promises, but it didn't work either, rendering always happened before my other two methods. I am sure I made a stupid mistake, but I really can't find it.
Any ideas? :/
Edit with my async/await stuff:
@override
public async onInit(): Promise<void> {
await this._getUserInformation();
await this._getLinks();
this._renderPlaceHolders();
}
private _getUserInformation() : Promise<any>
{
this.context.msGraphClientFactory
.getClient()
.then((client: MSGraphClient): void => {
client
.api('/me')
.select("some information")
.get((error, response: MicrosoftGraph.User, rawResponse?: any) => {
// do stuff
});
});
return Promise.resolve<any>();
}
private _getLinks() : Promise<any> {
let requestUrl = "url to sharepoint list";
this.context.spHttpClient.get(requestUrl, SPHttpClient.configurations.v1)
.then((response: SPHttpClientResponse) => {
if (response.ok) {
response.json().then((responseJSON) => {
if (responseJSON!=null && responseJSON.value!=null) {
let items:any[] = responseJSON.value;
items.forEach(element => {
// do stuff
});
}
});
}
});
return Promise.resolve<any>();
}
private _renderPlaceHolders() : void {
console.log("SmartpointPersonalizedRedirectApplicationCustomizer._renderPlaceHolders()");
console.log(
"Available placeholders: ",
this.context.placeholderProvider.placeholderNames
.map(name => PlaceholderName[name])
.join(", ")
);
// Handling the top placeholder
if (!this._topPlaceholder) {
this._topPlaceholder = this.context.placeholderProvider.tryCreateContent(
PlaceholderName.Top,
{ onDispose: this._onDispose }
);
// The extension should not assume that the expected placeholder is available.
if (!this._topPlaceholder) {
console.error("The expected placeholder (Top) was not found.");
return;
}
if (this._topPlaceholder.domElement) {
this._topPlaceholder.domElement.innerHTML = `
some html`;
}
}
}
Решение
You are resolving the promises without waiting the completation of the asyncronous calls inside methods and without returning anything.
Can you try this code?
private _getUserInformation() : Promise<any>
{
return this.context.msGraphClientFactory
.getClient()
.then((client: MSGraphClient): void => {
client
.api('/me')
.select("some information")
.get((error, response: MicrosoftGraph.User, rawResponse?: any) => {
// do stuff
});
});
}
private _getLinks() : Promise<any> {
let requestUrl = "url to sharepoint list";
return this.context.spHttpClient.get(requestUrl, SPHttpClient.configurations.v1)
.then((response: SPHttpClientResponse) => {
if (response.ok) {
return response.json().then((responseJSON) => {
if (responseJSON!=null && responseJSON.value!=null) {
let items:any[] = responseJSON.value;
return items.forEach(element => {
// do stuff
});
}
});
}
});
}
It should be the same of:
private _getUserInformation() : Promise<any>
{
const res = this.context.msGraphClientFactory
.getClient()
.then((client: MSGraphClient): void => {
client
.api('/me')
.select("some information")
.get((error, response: MicrosoftGraph.User, rawResponse?: any) => {
// do stuff
});
});
return Promise.resolve<any>(res);
}
private _getLinks() : Promise<any> {
let requestUrl = "url to sharepoint list";
const res = this.context.spHttpClient.get(requestUrl, SPHttpClient.configurations.v1)
.then((response: SPHttpClientResponse) => {
if (response.ok) {
return response.json().then((responseJSON) => {
if (responseJSON!=null && responseJSON.value!=null) {
let items:any[] = responseJSON.value;
return items.forEach(element => {
// do stuff
});
}
});
}
});
return Promise.resolve<any>(res);
}
Не связан с sharepoint.stackexchange