Hiren Changela
Hiren Changela

Reputation: 1

While we are create list and list columns using "pnp/sp". Why some of the columns are not created in one go?

While we are create list and list columns using pnp/sp. Why some of the columns are not created in one go? We need to run again then it will created. Please help me to resolve this issue.

I have used SPFx solution with react and "pnp/sp". Please refer below configuration for the same.

Please refer below code snippet for the same.

import { sp } from '@pnp/sp';
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import "@pnp/sp/fields";
import "@pnp/sp/views";
import { UrlFieldFormatType } from "@pnp/sp/fields";

export const trainingsList = async () => {
    try {
        const listEnsureResult = await sp.web.lists.ensure("Trainings", "Trainings", 100, false, { Hidden: false });
        if (listEnsureResult.created) {
            return listEnsureResult;
        }

    } catch (error) {
        console.log("Error in Trainings List", error);
    }
}

export const trainingsFields = async () => {
    const courseList = await sp.web.lists.getByTitle("Course")();
    try {
        await sp.web.lists.getByTitle("Trainings").fields.select("*").get().then(async (res) => {
            let listData = [];
            res.forEach(ele => {
                listData.push(ele.InternalName);
            });

            if (listData.indexOf("VideoUrl") == -1) {
                setTimeout(() => {
                    sp.web.lists.getByTitle("Trainings").fields.addUrl("VideoUrl", UrlFieldFormatType.Hyperlink).then(() => {
                        sp.web.lists.getByTitle("Trainings").defaultView.fields.add("VideoUrl");
                    })
                }, 5000);
            }

            if (listData.indexOf("Walkthrough") == -1) {
                sp.web.lists.getByTitle("Trainings").fields.addMultilineText("Walkthrough").then(() => {
                    sp.web.lists.getByTitle("Trainings").defaultView.fields.add("Walkthrough");
                });
            }

            if (listData.indexOf("Status") == -1) {
                sp.web.lists.getByTitle("Trainings").fields.addBoolean("Status").then(() => {
                    sp.web.lists.getByTitle("Trainings").defaultView.fields.add("Status");
                });
            }

            if (listData.indexOf("TrainingDuration") == -1) {
                sp.web.lists.getByTitle("Trainings").fields.addNumber("TrainingDuration").then(() => {
                    sp.web.lists.getByTitle("Trainings").defaultView.fields.add("TrainingDuration");
                });
            }

            if (listData.indexOf("Course") == -1) {
                sp.web.lists.getByTitle("Trainings").fields.addLookup("Course", courseList.Id, "Title").then(() => {
                    sp.web.lists.getByTitle("Trainings").defaultView.fields.add("Course");
                });
            }

            await sp.web.lists.getByTitle("Trainings").fields.select("*").get().then(async (resListData) => {
                let listColumnData = [];
                resListData.forEach(ele => {
                    listColumnData.push(ele.InternalName);
                });
                console.log("listColumnData...", listColumnData);

                if (listColumnData.indexOf("VideoUrl") != -1 && listColumnData.indexOf("Walkthrough") != -1 && listColumnData.indexOf("Status") != -1 && listColumnData.indexOf("TrainingDuration") != -1 && listColumnData.indexOf("Course") != -1) {
                    console.log("Inside IF.....");
                }
                else {
                    console.log("Inside ELSE.....");
                    await trainingsFields();
                }
            }).catch((err) => {
                console.log("Error in trainings fields creation", err);
            });
            console.log("Trainings fields created successfully!");
        }).catch((err) => {
            console.log("Error in Trainings fields", err);
        });
    } catch (error) {
        console.log("Error in Trainings fields", error);
    }
}

Upvotes: 0

Views: 476

Answers (1)

Nikolay
Nikolay

Reputation: 12245

You need to use await with add functions, otherwise your function may terminate before all fields are created. In general, I would avoid mixing await with .then for simplicity. Consider something like:

if (listData.indexOf("Walkthrough") == -1) {
 await sp.web.lists.getByTitle("Trainings").fields.addMultilineText("Walkthrough");
 await sp.web.lists.getByTitle("Trainings").defaultView.fields.add("Walkthrough");
}

if (listData.indexOf("Status") == -1) {
 await sp.web.lists.getByTitle("Trainings").fields.addBoolean("Status");
 await sp.web.lists.getByTitle("Trainings").defaultView.fields.add("Status");
}

Normally, you should get a linter (or compiler) error or warning when you try to call an asynchronous function without waiting for it to terminate in some way (i.e. without await or .then or .catch), i.e. "shooting in the air", but this may depend on the linter settings, as far as I remember.

TLDR: replace all foo().then(result => ..) with const result = await foo() and you should be fine.

Another thing, there may be a much more efficient way to create fields not just in "one go" but in "one call", if you used batches, for example.

Upvotes: 0

Related Questions