Pnpjs: @pnp Adding Site Column to List

Created on 19 Sep 2018  Â·  4Comments  Â·  Source: pnp/pnpjs

Category

  • [ ] Enhancement
  • [ ] Bug
  • [# ] Question
  • [ ] Documentation gap/issue

Hello there

Wondering if you can answer this current issue i'm having. I can successfully create a Site column, i then want to add this newly created column to an existing document library. This is a snippet from my code:

`const web = new Web(this.props.siteUrl);
web.fields.addChoice(validateTextbox, listAddedChoices, ChoiceFieldFormatType.Dropdown, true,
{ Group: 'RW DMS Columns', FieldTypeKind: FieldTypes.Choice, EnforceUniqueValues: true, Required: isCheckedRequired, Description: validateTextArea }).then((result: FieldAddResult) => {

web.lists.getByTitle(item.replace(//g, '')).fields.createFieldAsXml(result.data.SchemaXml).then((data: FieldAddResult) => {

}).catch(error => {
this.setState({ errorText: validateTextbox + ' created successful, but something went wrong while adding the column to ' + item.replace(//g, '') + ' document library. ' + error });
});
});`

I'm trying to use fields.createFieldAsXml(result.data.SchemaXml). This is the schema xml from the newly created column. I get 500 error: "This field must be indexed to enforce unique values"

I'm not even sure this is the right way as it's had to find this document anywhere. I tried looking at the REST API reference but doesn't cover this scope of adding existing site column to list fields.

Thanks as ever

code answered question

All 4 comments

Hi @Mike-tech,

When adding a unique field in a list it should be indexed.
You have 2 options here, remove uniqueness flag or add index one, e.g.:

import { sp, ChoiceFieldFormatType, FieldTypes } from "@pnp/sp";

(async () => {

    const web = sp.web; // new Web(this.props.siteUrl);
    const list = web.lists.getByTitle('Tasks');

    const field = await web.fields.addChoice('validateTextbox_02', ['Option 1', 'Option 2'], ChoiceFieldFormatType.Dropdown, true, {
        Group: 'RW DMS Columns',
        FieldTypeKind: FieldTypes.Choice,
        EnforceUniqueValues: true, // or comment these guys if no unique option is needed
        Indexed: true,     // and this...
        Required: true,
        Description: ''
    });

    await list.fields.createFieldAsXml(field.data.SchemaXml);
    console.log('Done');

})()
    .catch(console.log);

@koltyakov massive thanks and for quick response. Yes this is working now. Glad to see i was on the right path.

One more quick question/advice: I need to add the column to the list default view. I know i need to do .defaultView.fields.add.fields. My question is could one include this in a batch and achieve within one request or should i do this in a second request after success completion of adding the column to the list?

Cheers

Mike,

Yes, fields can be added to a view in one call using batch API:

import { sp } from "@pnp/sp";

(async () => {

    const web = sp.web; // new Web(this.props.siteUrl);
    const list = web.lists.getByTitle('Tasks');

    const batch = web.createBatch();
    const fields = ['validateTextbox_01', 'validateTextbox_02'];

    // await list.defaultView.fields.removeAll(); // to clean then recreate a view

    let errors: string[] = [];
    for (const field of fields) {
        list.defaultView.fields
            .inBatch(batch).add(field)
            .catch(error => errors.push(error.message));
    }

    await batch.execute();

    if (errors.length > 0) {
        throw new Error(`Error: ${errors.join('\n')}`);
    }

    console.log('Done');

})()
    .catch(console.log);

@koltyakov you a star!

I wasn't sure when in batch if order of execution is respected and awaited.

Many thanks again sir

Was this page helpful?
0 / 5 - 0 ratings