javascripttypescriptsharepointspfxsharepointframework

Can't create a LookUpField


I am creating a new list and trying to add a LookUp field on the list.

I retrieve the list I want to look up against:

let list = sp.web.lists.getByTitle("Trucks");
    list.get().then(list => {
        this._ensureMyList("MySPListTest", list)
    }); 

I then create the new list and the new field:

private _ensureMyList(listName: string, truckList): void {
    sp.web.lists.ensure(listName)
        .then((ler: ListEnsureResult) => {
            if (ler.created) {
                console.log("list was created");

                ler.list.fields.add("LookupTest", "SP.FieldLookup", { 
                    Group: "~Example",
                    FieldTypeKind: 7,
                    Filterable: true,
                    Hidden: false,
                    EnforceUniqueValues: true,
                })
                    .then((result) => {
                        console.log("result: ", result);
                    });
            }
        });
}

I get the error:

Uncaught (in promise) Error: Error making HttpClient request in queryable: [500]  ::> {"responseBody":{"odata.error":{"code":"-2146232832, Microsoft.SharePoint.SPException","message":{"lang":"en-US","value":"Please use addfield to add a lookup field instead."}}},"responseHeaders":{}}

I got the Field name and TypeKind from:

https://msdn.microsoft.com/en-us/library/office/dn600182.aspx#bk_FieldLookup

I also tried using the addLookup method:

ler.list.fields.addLookup("LookupTest", truckList.Id, "Truck")
    .then((result) => {
        console.log("result: ", result);
    });

With error:

Uncaught (in promise) Error: Error making HttpClient request in queryable: [400]  ::> {"responseBody":{"odata.error":{"code":"-1, Microsoft.SharePoint.Client.InvalidClientQueryException","message":{"lang":"en-US","value":"The parameter __metadata does not exist in method AddField."}}},"responseHeaders":{}}

Solution

  • You could consider the following options to add lookup field:

    1) via Fields.addLookup method:

    let list = await sp.web.lists.getByTitle(listTitle);  //get list resource
    let lookupList = await sp.web.lists.getByTitle(lookupListTitle).select("Id").get();  //select Lookup List Id 
    let field = await list.fields.addLookup(lookupFieldName, lookupList.Id ,"Title"); // add lookup field to list
    

    2) via Fields.createFieldAsXml method:

    let list = await sp.web.lists.getByTitle(listTitle); //get target list resource
    let lookupList = await sp.web.lists.getByTitle("Categories").select("Id").get(); //determine lookup list id
    let fieldXml = `<Field Name="Category" Type="Lookup" DisplayName="Category" List="{${lookupList.Id}}" ShowField="Title"/>`;  //construct lookup field schema
    let field = await list.fields.createFieldAsXml(fieldXml);  //add field to list
    

    References

    PnPjs Add Fields

    Update

    Regarding the error which occurs while invoking Fields.addLookup method:

    the parameter __metadata does not exist in method AddField.

    it seems there is a bug with in the latest version (v1.2.1) for Fields.addLookup method. The point is it generates invalid payload, something like this:

    {
       "__metadata":{
         "type":"SP.FieldCreationInformation"
       },
       "parameters": { 
              "FieldTypeKind":7,
              "LookupFieldName":"Title",
              "LookupListId":"{list-id}",
              "Title":"Cat"
       }
    } 
    

    parameters should be the root tag in payload for http://<site url>/_api/web/lists(guid'<list id>')/fields('<field id>')/addfield endpoint (source)

    According to the history this bug has been introduced with one of the later commit, anyway it's better to report an issue.