0

I am using spfx with react framework/pnp-js.t In a form I have total 8 dropdowns.I want to render data to these fields from 8 different sharepoint lists through one function only.

I tried implementing this thing for one drodown say 'City'. But stuck in using the same function for rest of 7 dropdowns. I understand that we can pass a listName dynamically while calling a function but how to dynamically store the data retrived to different constants or arrays.

const locoptions: IDropdownOption[] = [
    { key: 'city', text: 'City', itemType: DropdownMenuItemType.Header }
];

<Dropdown  label="City" defaultSelectedKey="Pune" required={true}
 options={locoptions} styles={dropdownStyles} />


public componentWillMount()
{
    this.getDropdownData('Cities');

}

public getDropdownData(listName:string)
{
    sp.web.lists.getByTitle(listName).items.get().then((items: any[]) => 
    {

        for(let i=0;i<items.length;i++)
        {
            locoptions.push({
            key: items[i].Id,
            text: items[i].Title
        });
        }
    });

  }
K Kritis
  • 1
  • 4

1 Answers1

0

how to dynamically store the data retrived to different constants or arrays.

Here you are:

const locoptions: {[key: string]: IDropdownOption[]} = {
    Cities: [
        { key: 'city', text: 'City', itemType: DropdownMenuItemType.Header }
    ]
};

...

locoptions[listName].push({
    key: items[i].Id,
    text: items[i].Title
});

UPDATE

I really try to help you. I don't see all code of your component, that's why I can misinterpret your code. Also, I can't create a working example for you.

I expect that you are using TypeScript.

If you want to rerender your component when you get new data for your dropdown, you have to use state of the React component:

//Interface for Component Props
interface IYourComponentProps {
    locoptions: {[key: string]: IDropdownOption[]}
}

//Interface for Component State
interface IYourComponentState {
    locoptions: {[key: string]: IDropdownOption[]}
}


//this is config for default options of your dropdowns
const defaultOptions: {[key: string]: IDropdownOption[]} = {
    Cities: [
        { key: 'city', text: 'City', itemType: DropdownMenuItemType.Header }
    ]
};



class YourComponent extends React.Component<IYourComponentProps, IYourComponentState> {
    public state = {
        locoptions: defaultOptions //set default options to state
    };

    public componentWillMount() {
        this.getDropdownData('Cities');
    }

    public getDropdownData(listName: string) {
        return sp.web.lists.getByTitle(listName).items.get().then((items: any[]) => {

            // process items to get array of options  
            const options = items.map((item) => {
                return {
                    key: item.Id,
                    text: item.Title
                };
            });

            // take defaultOptions as first options, if we don't have default options, then we get empty array
            const firstOptions = defaultOptions[listName] || [];

            // set new state
            this.setState({
                locoptions: {
                    ...this.state.locoptions,
                    [listName]: [
                        ...firstOptions,
                        ...options
                    ]
                }
            });
        });

    }

    public render() {
        return (
            <Dropdown  label="City" defaultSelectedKey="Pune" required={true} options={this.state.locoptions} styles={dropdownStyles} />
        )
    }
}


Andrii Golubenko
  • 4,879
  • 1
  • 22
  • 27
  • Thanks for the quick Response but I have one query. Should I write options attribute like options={locoptions['Cities']} and also call the getDropDownData('Cities')? – K Kritis May 15 '19 at 12:03
  • yes you should. Or you could create component-wrapper of your `Dropdown` with props `listName` and `defaultOptions`. This component will render Dropdown and retrieve options for it. And then you could use this component instead of `Dropdown` – Andrii Golubenko May 15 '19 at 12:12
  • locpotions[listName].push(); is giving error "Uncaught (in promise) TypeError: Cannot read property 'push' of undefined" – K Kritis May 15 '19 at 13:15
  • @KKritis Have you created this propery in `locpotions` before adding of value? You have to check if `locpotions[listName]` exist and if not, you have to create it before adding of value to the array. – Andrii Golubenko May 15 '19 at 13:27
  • @KKritis you can add the full code of the component to your question, and I will help you. – Andrii Golubenko May 15 '19 at 13:28
  • I can't share the whole component because it's project specific. I have used locoptions on three places only. 1)const locoptions: {[key: string]: IDropdownOption[]} = { Cities: [ { key: 'city', text: 'City', itemType: DropdownMenuItemType.Header } ] }; 2)locoptions[listName].push() 3) – K Kritis May 16 '19 at 10:05
  • If you get what I said above,do help me. Because I cannot move forward without figuring this out. – K Kritis May 16 '19 at 10:08