1

I use DropDownMenu and take a reference from official doumcn https://shoutem.github.io/docs/ui-toolkit/components/dropdown-menu

I want to set two DropDownMenu the first is for zone and the second is for city, if user select the zone like East the second DropDownMenu should set the value E1、E2

Here is my code:

import React, { Component } from 'react';
import { View } from 'react-native';
import { DropDownMenu, Text } from '@shoutem/ui';

class TestConfirm extends Component {

    constructor(props) {
        super(props);
        this.state = {
          zone: [
            {
              id: 0,
              brand: "North",
              models:
                {
                  model: "Audi R8",
                  image: {
                    url: "https://shoutem.github.io/img/ui-toolkit/dropdownmenu/Audi-R8.jpg"
                  },
                  description: "North Description"
                },
                children: [{
                    name: "N1",
                    id: 10,
                  },{
                    name: "N2",
                    id: 17,
                  }]
              },
            {
              id: 1,
              brand: "West",
              models: {
                model: "Chiron",
                image: {
                  url: "https://shoutem.github.io/img/ui-toolkit/dropdownmenu/Chiron.jpg"
                },
                description: "West Description"
              },
              children: [{
                name: "W1",
                id: 10,
              },{
                name: "W2",
                id: 17,
              }]
            },
            {
              id: 2,
              brand: "East",
              models: {
                model: "Dodge Viper",
                image: {
                  url: "https://shoutem.github.io/img/ui-toolkit/dropdownmenu/Dodge-Viper.jpg"
                },
                description: "East Description"
              },
              children: [{
                name: "E1",
                id: 10,
              },{
                name: "E2",
                id: 17,
              }]
            },
          ],
        }
      }

  render() {
    const selectedZone = this.state.selectedZone || this.state.zone[0];
    console.log('selectedZone =>');
    console.log(selectedZone);
    console.log('selectedZone.children =>');
    console.log(selectedZone.children);
    return (
      <Screen>
        <DropDownMenu
            styleName="horizontal"
            options={this.state.zone}
            selectedOption={selectedZone ? selectedZone : this.state.zone[0]}
            onOptionSelected={(zone) => this.setState({ selectedZone: zone })}
            titleProperty="brand"
            valueProperty="cars.model"
        />
        <Text styleName="md-gutter-horizontal">
            {selectedZone ?
            selectedZone.models.description :
            this.state.zone[0].models.description}
        </Text>

       <DropDownMenu
            styleName="horizontal"
            options={selectedZone.children}
            selectedOption={selectedZone ? selectedZone : this.state.zone[0].children}
            onOptionSelected={(city) => this.setState({ selectedZone: city })}
            titleProperty="name"
            valueProperty="cars.model"
        />
      </Screen>
    );
  }
}

export default TestConfirm;

Here is my screen look like this: enter image description here

If i select East it will show error

Invalid `selectedOption` {"id":2,"brand":"East","models":{"model":"Dodge Viper","image":{"url":"https://shoutem.github.io/img/ui-toolkit/dropdownmenu/Dodge-Viper.jpg"},"description":"East Description"},"children":[{"name":"E1","id":10},{"name":"E2","id":17}]}, DropDownMenu `selectedOption` must be a member of `options`.Check that you are using the same reference in both `options` and `selectedOption`.

I check my console.log will look like this: enter image description here

The key children under the name is what i want to put it into my second DropDownMenu

I have no idea how to do next step. Any help would be appreciated.

Thanks in advance.

Morton
  • 5,380
  • 18
  • 63
  • 118
  • 1
    `this.state.zone[0].children` is an array. try using `this.state.zone[0].children[0]` – bennygenel May 12 '18 at 08:57
  • Looks like it will be corrected. But i try it and it still shows the same error :( – Morton May 12 '18 at 09:02
  • Thank you @bennygenel . I fix it like this `selectedOption={selectedZone ? selectedZone.children[0] : this.state.zone[0].children[0]}` Its working now. Can you post it and i will take the answer. – Morton May 12 '18 at 09:06
  • is there a way to show image and text in dropdown list? – Kartiikeya Aug 08 '18 at 06:39
  • I'm not sure about that, all i put the data into DropDownMenu is String array, I suggest you can ask it on official github. – Morton Aug 08 '18 at 09:48

1 Answers1

1

selectedOption property for the DropDownMenu component expects a single object but this.state.zone[0].children is an array. You can change it to this.state.zone[0].children[0] to fixed the problem.

Also when you change the city dropdown you are updating the zone value in state. This will cause a bug. Try fixing it with setting a different value in state and checking that value for the city dropdown

Sample

render() {
    const { zone, selectedZone, selectedCity } = this.state
    return (
      <Screen>
        <DropDownMenu
            styleName="horizontal"
            options={zone}
            selectedOption={selectedZone || zone[0]}
            onOptionSelected={(zone) => 
              this.setState({ selectedZone: zone, selectedCity: zone.children[0] } )
            }
            titleProperty="brand"
            valueProperty="cars.model"
        />
        <Text styleName="md-gutter-horizontal">
            {selectedZone ?
            selectedZone.models.description :
            this.state.zone[0].models.description}
        </Text>
       <DropDownMenu
            styleName="horizontal"
            options={selectedZone ? selectedZone.children : zone[0].children } // check if zone selected or set the defaul zone children
            selectedOption={selectedCity || zone[0].children[0] } // set the selected city or default zone city children
            onOptionSelected={(city) => this.setState({ selectedCity: city })} // set the city on change
            titleProperty="name"
            valueProperty="cars.model"
        />
      </Screen>
    );
  }
bennygenel
  • 23,896
  • 6
  • 65
  • 78
  • There is no way to set the second `DropDownMenu` state. looks like i should create another state object. :( – Morton May 12 '18 at 10:23
  • @徐博俊 what do you mean by that? – bennygenel May 12 '18 at 10:24
  • I mean for example the East has the children E1 and E2, if select E2 what ever i use `this.setState` the East still has the children E1 and E2. How the second `DropDownMenu` knows he should set the value for E1 or E2 ? – Morton May 12 '18 at 10:29
  • 1
    @徐博俊 updated question with a sample code. hope it helps – bennygenel May 12 '18 at 10:39
  • Thank you. Try your code, show error `TypeError: Cannot read property 'children' of undefined`. It looks like there is no selectedZone.children, should i restructure my state object ? – Morton May 12 '18 at 10:59
  • Sorry i forgot remove `console.log` .The error is gone now. I try it again find that still has another issue is if i select West or East the second `DropDownMenu` value is gone. Show the error `Invalid `selectedOption` {"name":"N1","id":10}, DropDownMenu selectedOption must be a member of options.Check that you are using the same reference in both options and selectedOption` Any idea ? Thank you again. – Morton May 12 '18 at 11:12
  • 1
    @徐博俊 I missed something and fixed the sample. You need to set the city for a default value when the zone changed. Check the sample code now for the change. – bennygenel May 12 '18 at 11:57
  • It is really helps me a lot. I don't even think i can use set state like this. Its working now. Thank you very much @bennygenel – Morton May 12 '18 at 12:33