2017-11-11 154 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

這個答案並不能真正解決我的問題 –