TypeScript/SPFx Promises throws Exception("Cannot read property 'then' of undefined") 但似乎有效
TypeScript/SPFx Promises throws Exception("Cannot read property 'then' of undefined") but seems to work
我尝试创建一个 SPFx Webpart。在创建新项目之前,我需要调用 0-4 次 _ensureUser
,具体取决于 Client
、AssignedTo
、ResolvedBy
和 Referrer
的任意组合已经设置好了。完成所有必需的 _ensureUser
调用后,即可创建新项目。
代码在托管 workbench 上调试时运行,但当我调用 userPromises[0].then( (value: {}) => { ...
或 Promise.all(userPromises).then( (value: {}[]) => { ...
时抛出异常。当我点击 F5/continue 时,剩下的部分被执行,新项目被创建。 _ensureUser
当我直接调用它并将它与 then 链接在一起时工作,而不是先将它放在 userPromises 数组中。
我认为问题是 _ensureUser
不是 return 和 Promise
。如果是这样,我该怎么做?我应该重组_ensureUser
and/orcreateItem
吗?我需要在某处调用 bind 吗?
createItem
函数:
public createItem( logItem: IInteractionLogItem): Promise<IInteractionLogItem[]> {
const userPromises: Promise<{}>[] = [];
if(logItem.Client && logItem.Client.AccountName){
userPromises.push(this._ensureUser(logItem.Client));
}
if(logItem.AssignedTo && logItem.AssignedTo.AccountName){
userPromises.push(this._ensureUser(logItem.AssignedTo));
}
if(logItem.ResolvedBy && logItem.ResolvedBy.AccountName){
userPromises.push(this._ensureUser(logItem.ResolvedBy));
}
if(logItem.Referrer && logItem.Referrer.AccountName){
userPromises.push(this._ensureUser(logItem.Referrer));
}
console.log("SharePointDataProvider.CreateItem: userPromises.length=" + userPromises.length);
if( userPromises.length == 0) {
const batch: SPHttpClientBatch = this.webPartContext.spHttpClient.beginBatch();
const batchPromises: Promise<{}>[] = [
this._createItem(batch, logItem),
this._getItemsBatched(batch)
];
return this._resolveBatch(batch, batchPromises);
} else if( userPromises.length == 1) {
userPromises[0].then( (value: {}) => {
const batch: SPHttpClientBatch = this.webPartContext.spHttpClient.beginBatch();
const batchPromises: Promise<{}>[] = [
this._createItem(batch, logItem),
this._getItemsBatched(batch)
];
return this._resolveBatch(batch, batchPromises);
});
} else {
Promise.all(userPromises).then( (value: {}[]) => {
const batch: SPHttpClientBatch = this.webPartContext.spHttpClient.beginBatch();
const batchPromises: Promise<{}>[] = [
this._createItem(batch, logItem),
this._getItemsBatched(batch)
];
return this._resolveBatch(batch, batchPromises);
});
}
}
_ensureUser
函数:
private _ensureUser( user: IInteractionLogPerson): Promise<ISPUser> {
console.log("SharePointDataProvider.EnsureUser( \"" + user.AccountName + "\" )");
var data = {logonName: user.AccountName};
return this._webPartContext.spHttpClient.post(
this._ensureUserUrl,
SPHttpClient.configurations.v1,
{ body: JSON.stringify(data) } ).then(
(value: SPHttpClientResponse) => {
console.log("SharePointDataProvider.EnsureUser Got Http Response:\"" + value.statusText + "\"" );
return value.json();
},
(error: any) => console.log("SharePointDataProvider.EnsureUser Rejected: " + error )
).then((spUser: ISPUser) => {
console.log("SharePointDataProvider.EnsureUser Set Id:" + spUser.Id +" LoginName:\"" + spUser.LoginName + "\"" );
user.Id = spUser.Id;
return spUser;
});
}
1 _ensureUser
调用的调试输出:
SharePointDataProvider.EnsureUser( "i:0#.f|membership|bob@pc.org.nz" )
SharePointDataProvider.CreateItem: userPromises.length=1
TypeError: Cannot read property 'then' of undefined
at ILoggerContainer._createInteractionLogItem (d:\spfx\iLogger-webpart\dist\i-logger.bundle.js:22103:60)
at ILoggerForm._handleAddButtonClick (d:\spfx\iLogger-webpart\dist\i-logger.bundle.js:23173:21)
at Object.r (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:75541)
at a (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:30260)
at Object.s [as executeDispatchesInOrder] (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:30475)
at f (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:26933)
at m (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:27059)
at Array.forEach (<anonymous>)
at r (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:112499)
at Object.processEventQueue (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:28121)
SharePointDataProvider.EnsureUser Got Http Response:"OK"
SharePointDataProvider.EnsureUser Set Id:13 LoginName:"i:0#.f|membership|bob@pc.org.nz"
2 个 _ensureUser
调用的调试输出:
SharePointDataProvider.EnsureUser( "i:0#.f|membership|dennis@carehouse.org.nz" )
SharePointDataProvider.EnsureUser( "i:0#.f|membership|bob@pc.org.nz" )
SharePointDataProvider.CreateItem: userPromises.length=2
TypeError: Cannot read property 'then' of undefined
at ILoggerContainer._createInteractionLogItem (d:\spfx\iLogger-webpart\dist\i-logger.bundle.js:22103:60)
at ILoggerForm._handleAddButtonClick (d:\spfx\iLogger-webpart\dist\i-logger.bundle.js:23173:21)
at Object.r (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:75541)
at a (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:30260)
at Object.s [as executeDispatchesInOrder] (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:30475)
at f (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:26933)
at m (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:27059)
at Array.forEach (<anonymous>)
at r (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:112499)
at Object.processEventQueue (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:28121)
SharePointDataProvider.EnsureUser Got Http Response:"OK"
SharePointDataProvider.EnsureUser Set Id:10 LoginName:"i:0#.f|membership|dennis@carehouse.org.nz"
SharePointDataProvider.EnsureUser Got Http Response:"OK"
SharePointDataProvider.EnsureUser Set Id:13 LoginName:"i:0#.f|membership|bob@pc.org.nz"
我需要在调用 userPromises[0].then( (value: {}) => { ...
或 Promise.all(userPromises).then( (value: {}[]) => { ...
之前添加一个 return
。该代码现在可以使用以下修改:
return userPromises[0].then( (value: {}) => {
和
return Promise.all(userPromises).then( (value: {}[]) => {
return ctx.spHttpClient.get(
url+'/_api/web/lists',
SPHttpClient.configurations.v1,
{
headers: [
['accept', 'application/json;odata.metadata=none']
]
}
).then((response: SPHttpClientResponse):Promise<ILists> => {
return response.json();
});
我尝试创建一个 SPFx Webpart。在创建新项目之前,我需要调用 0-4 次 _ensureUser
,具体取决于 Client
、AssignedTo
、ResolvedBy
和 Referrer
的任意组合已经设置好了。完成所有必需的 _ensureUser
调用后,即可创建新项目。
代码在托管 workbench 上调试时运行,但当我调用 userPromises[0].then( (value: {}) => { ...
或 Promise.all(userPromises).then( (value: {}[]) => { ...
时抛出异常。当我点击 F5/continue 时,剩下的部分被执行,新项目被创建。 _ensureUser
当我直接调用它并将它与 then 链接在一起时工作,而不是先将它放在 userPromises 数组中。
我认为问题是 _ensureUser
不是 return 和 Promise
。如果是这样,我该怎么做?我应该重组_ensureUser
and/orcreateItem
吗?我需要在某处调用 bind 吗?
createItem
函数:
public createItem( logItem: IInteractionLogItem): Promise<IInteractionLogItem[]> {
const userPromises: Promise<{}>[] = [];
if(logItem.Client && logItem.Client.AccountName){
userPromises.push(this._ensureUser(logItem.Client));
}
if(logItem.AssignedTo && logItem.AssignedTo.AccountName){
userPromises.push(this._ensureUser(logItem.AssignedTo));
}
if(logItem.ResolvedBy && logItem.ResolvedBy.AccountName){
userPromises.push(this._ensureUser(logItem.ResolvedBy));
}
if(logItem.Referrer && logItem.Referrer.AccountName){
userPromises.push(this._ensureUser(logItem.Referrer));
}
console.log("SharePointDataProvider.CreateItem: userPromises.length=" + userPromises.length);
if( userPromises.length == 0) {
const batch: SPHttpClientBatch = this.webPartContext.spHttpClient.beginBatch();
const batchPromises: Promise<{}>[] = [
this._createItem(batch, logItem),
this._getItemsBatched(batch)
];
return this._resolveBatch(batch, batchPromises);
} else if( userPromises.length == 1) {
userPromises[0].then( (value: {}) => {
const batch: SPHttpClientBatch = this.webPartContext.spHttpClient.beginBatch();
const batchPromises: Promise<{}>[] = [
this._createItem(batch, logItem),
this._getItemsBatched(batch)
];
return this._resolveBatch(batch, batchPromises);
});
} else {
Promise.all(userPromises).then( (value: {}[]) => {
const batch: SPHttpClientBatch = this.webPartContext.spHttpClient.beginBatch();
const batchPromises: Promise<{}>[] = [
this._createItem(batch, logItem),
this._getItemsBatched(batch)
];
return this._resolveBatch(batch, batchPromises);
});
}
}
_ensureUser
函数:
private _ensureUser( user: IInteractionLogPerson): Promise<ISPUser> {
console.log("SharePointDataProvider.EnsureUser( \"" + user.AccountName + "\" )");
var data = {logonName: user.AccountName};
return this._webPartContext.spHttpClient.post(
this._ensureUserUrl,
SPHttpClient.configurations.v1,
{ body: JSON.stringify(data) } ).then(
(value: SPHttpClientResponse) => {
console.log("SharePointDataProvider.EnsureUser Got Http Response:\"" + value.statusText + "\"" );
return value.json();
},
(error: any) => console.log("SharePointDataProvider.EnsureUser Rejected: " + error )
).then((spUser: ISPUser) => {
console.log("SharePointDataProvider.EnsureUser Set Id:" + spUser.Id +" LoginName:\"" + spUser.LoginName + "\"" );
user.Id = spUser.Id;
return spUser;
});
}
1 _ensureUser
调用的调试输出:
SharePointDataProvider.EnsureUser( "i:0#.f|membership|bob@pc.org.nz" )
SharePointDataProvider.CreateItem: userPromises.length=1
TypeError: Cannot read property 'then' of undefined
at ILoggerContainer._createInteractionLogItem (d:\spfx\iLogger-webpart\dist\i-logger.bundle.js:22103:60)
at ILoggerForm._handleAddButtonClick (d:\spfx\iLogger-webpart\dist\i-logger.bundle.js:23173:21)
at Object.r (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:75541)
at a (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:30260)
at Object.s [as executeDispatchesInOrder] (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:30475)
at f (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:26933)
at m (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:27059)
at Array.forEach (<anonymous>)
at r (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:112499)
at Object.processEventQueue (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:28121)
SharePointDataProvider.EnsureUser Got Http Response:"OK"
SharePointDataProvider.EnsureUser Set Id:13 LoginName:"i:0#.f|membership|bob@pc.org.nz"
2 个 _ensureUser
调用的调试输出:
SharePointDataProvider.EnsureUser( "i:0#.f|membership|dennis@carehouse.org.nz" )
SharePointDataProvider.EnsureUser( "i:0#.f|membership|bob@pc.org.nz" )
SharePointDataProvider.CreateItem: userPromises.length=2
TypeError: Cannot read property 'then' of undefined
at ILoggerContainer._createInteractionLogItem (d:\spfx\iLogger-webpart\dist\i-logger.bundle.js:22103:60)
at ILoggerForm._handleAddButtonClick (d:\spfx\iLogger-webpart\dist\i-logger.bundle.js:23173:21)
at Object.r (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:75541)
at a (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:30260)
at Object.s [as executeDispatchesInOrder] (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:30475)
at f (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:26933)
at m (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:27059)
at Array.forEach (<anonymous>)
at r (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:112499)
at Object.processEventQueue (https://spoprod-a.akamaihd.net/files/sp-client-prod_2017-06-30.017/sp-webpart-workbench-assembly_en-us_f3fed222daad2a0117a4c168deed7705.js:174:28121)
SharePointDataProvider.EnsureUser Got Http Response:"OK"
SharePointDataProvider.EnsureUser Set Id:10 LoginName:"i:0#.f|membership|dennis@carehouse.org.nz"
SharePointDataProvider.EnsureUser Got Http Response:"OK"
SharePointDataProvider.EnsureUser Set Id:13 LoginName:"i:0#.f|membership|bob@pc.org.nz"
我需要在调用 userPromises[0].then( (value: {}) => { ...
或 Promise.all(userPromises).then( (value: {}[]) => { ...
之前添加一个 return
。该代码现在可以使用以下修改:
return userPromises[0].then( (value: {}) => {
和
return Promise.all(userPromises).then( (value: {}[]) => {
return ctx.spHttpClient.get(
url+'/_api/web/lists',
SPHttpClient.configurations.v1,
{
headers: [
['accept', 'application/json;odata.metadata=none']
]
}
).then((response: SPHttpClientResponse):Promise<ILists> => {
return response.json();
});