2017-11-11 73 views
0

读取未定义的属性“然后”我有这样的错误:类型错误:无法在web服务

类型错误:未定义

at FactoryMethod.readItemsAndSetStatus (FactoryMethod.tsx:140:6) at FactoryMethod.componentDidMount (FactoryMethod.tsx:77:10)

调试器中断在这种方法不能读取属性“然后”(当时的声明):

// read items using factory method pattern and sets state accordingly 
    private readItemsAndSetStatus(): void { 
    this.setState({ 
     status: "Loading all items..." 
    }); 

    const factory: ListItemFactory = new ListItemFactory(); 
    factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName) 
    .then((items: IListItem[]) => { 
     const keyPart: string = this.props.listName === "GenericList" ? "" : this.props.listName; 
     // the explicit specification of the type argument `keyof {}` is bad and 
     // it should not be required. 
     this.setState<keyof {}>({ 
      status: `Successfully loaded ${items.length} items`, 
      ["Details" + keyPart + "ListItemState"] : { 
      items 
      }, 
      columns: buildColumns(items) 
     }); 
    }); 
    } 

工厂代码是这样的: (GenericList情况)

import { SPHttpClient, SPHttpClientResponse } from "@microsoft/sp-http"; 
import { IWebPartContext } from "@microsoft/sp-webpart-base"; 
import { IListItem} from "./models/IListItem"; 
import { IFactory } from "./IFactory"; 
import { INewsListItem } from "./models/INewsListItem"; 
import { IDirectoryListItem } from "./models/IDirectoryListItem"; 
import { IAnnouncementListItem } from "./models/IAnnouncementListItem"; 

export class ListItemFactory implements IFactory { 
    private _listItems: IListItem[]; 
    public getItems(requester: SPHttpClient, siteUrl: string, listName: string): Promise<IListItem[]> { 
     switch(listName) { 
      case "GenericList": 
       let items: IListItem[]; 
       // tslint:disable-next-line:max-line-length 
       requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id,Modified,Created,Author/Title,Editor/Title&$expand=Author,Editor`, 
       SPHttpClient.configurations.v1, 
       { 
        headers: { 
         "Accept": "application/json;odata=nometadata", 
         "odata-version": "" 
        } 
       }) 
       .then((response: SPHttpClientResponse): Promise<{ value: IListItem[] }> => { 
        return response.json(); 
       }) 
       .then((json: { value: IListItem[] }) => { 
        console.log(JSON.stringify(json.value)); 
        items=json.value.map((v,i)=>({ 
         key: v.id, 
         id: v.id, 
         title: v.title, 
         created: v.created, 
         createdby: v.Author.Title, 
         modified: v.modified, 
         modifiedby: v.Editor.Title       
        })); 
        return items; 
        }); 
       break;  
      case "News": 
       let newsitems: INewsListItem[]; 
       // tslint:disable-next-line:max-line-length 
       requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id,Modified,Created,Created By,Modified By,newsheader,newsbody,expiryDate`, 
       SPHttpClient.configurations.v1, 
       { 
        headers: { 
         "Accept": "application/json;odata=nometadata", 
         "odata-version": "" 
        } 
       }) 
       .then((response: SPHttpClientResponse): Promise<{ value: INewsListItem[] }> => { 
        return response.json(); 
       }) 
       .then((json: { value: INewsListItem[] }) => { 
        return this._listItems = json.value; 
       }); 
       break;  
      case "Announcements": 
       let announcementitems: IAnnouncementListItem[]; 
       requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`, 
       SPHttpClient.configurations.v1, 
       { 
        headers: { 
         "Accept": "application/json;odata=nometadata", 
         "odata-version": "" 
        } 
       }) 
       .then((response: SPHttpClientResponse): Promise<{ value: IAnnouncementListItem[] }> => { 
        return response.json(); 
       }) 
       .then((json: { value: IAnnouncementListItem[] }) => { 
        return this._listItems = json.value; 
       }); 
       break;  
      case "Directory": 
       let directoryitems: IDirectoryListItem[]; 
       requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`, 
       SPHttpClient.configurations.v1, 
       { 
        headers: { 
         "Accept": "application/json;odata=nometadata", 
         "odata-version": "" 
        } 
       }) 
       .then((response: SPHttpClientResponse): Promise<{ value: IDirectoryListItem[] }> => { 
        return response.json(); 
       }) 
       .then((json: { value: IDirectoryListItem[] }) => { 
        return this._listItems = json.value; 
       }); 
       break;  
      default: 
       return null; 
     } 
     } 
} 

我Ilistiteminterface代码

export interface IListItem { 
    [key: string]: any; 
    id: string; 
    title: string; 
    modified: Date; 
    created: Date; 
    modifiedby: string; 
    createdby: string; 
} 

的JSON从服务返回的是:

[{ 
    "Author": { 
     "Title": "Luis Valencia" 
    }, 
    "Editor": { 
     "Title": "Luis Valencia" 
    }, 
    "Id": 1, 
    "ID": 1, 
    "Title": "Generic List Item 1", 
    "Modified": "2017-10-23T20:02:22Z", 
    "Created": "2017-10-23T20:02:22Z" 
    }, 
    { 
    "Author": { 
     "Title": "Luis Valencia" 
    }, 
    "Editor": { 
     "Title": "Luis Valencia" 
    }, 
    "Id": 2, 
    "ID": 2, 
    "Title": "Generic List Item 2", 
    "Modified": "2017-11-07T17:52:34Z", 
    "Created": "2017-11-07T17:52:34Z" 
    } 
] 

调试的东西,我注意到那是什么时候的JSON地图显然是行不通的。 见截图,项目是未定义

enter image description here

+1

getItems()函数中的开关分支都没有返回任何东西。你需要实际返回Promise:所以'return requester.get(...)。then(...)' – Duncan

+0

@Duncan说了什么,你的默认情况下也需要返回一个promise。 –

+0

请精心设计,我不是专家,所以不知道如何解决它 –

回答

1

你不能从getItems返回请求者。在每个case语句中,在请求者之前添加一个return语句。

return requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}') ... 

。然后是一个方法和无极无极状物体,并且由于getItems要么返回undefined(或在默认情况下,空)则引发错误。

+0

不知道我明白了,你能详细阐述我需要解决的问题和方法吗? –

+0

例如:'case“Announcements”:return requester.get(...'getItems不知道如何返回给它的调用者,但没有为每个开关case返回语句。 – MynockSpit

+0

这个答案并不能真正解决我的问题 –