0

I have this picker:

<Picker
    style={{ width: "100%" }}
    mode="dropdown"
    selectedValue={move.client}
    onValueChange={this.handleChange("client")}
>
    {this.state.clients !== "" ? (
    this.state.clients.map(client => {
        <Picker.Item label={client.name} value={client.id} />;
    })
    ) : (
        <Picker.Item label="Loading..." value="0" />
    )}
</Picker>

I can't make the Picker.items to be the array that I want. It works just like that in React JS, but i can't make it work here.

And this is how I get the Clients array from my DB:

componentDidMount() {
        axios
            .get(`${API_URL}/clients`)
            .then(response => {
                this.setState({ clients: response.data });
            })
            .catch(error => console.log(error));
    }

I get this error

TypeError: Cannot read property 'props' of null

It seems that it renders the picker, but when I get the data from my DB it just crashes and I get this error. I just can't find what I'm doing wrong...

  • if the `client` variable is supposed to be an array, why are you checking to see if it's an empty string like this: `this.state.clients !== ""`? – Reza Shoja Jun 24 '19 at 12:03
  • I tried doing `{this.state.clients ? () : ()}` and it didn't work. I tried `!== []` and no luck with this one so I just tried that, and it doesn't work either.... –  Jun 24 '19 at 12:05
  • have you tried logging your clients like this: `console.log(clients) && console.log(typeof clients)` to see what it returns? anyway if it's array you should check like this: `clients.length>0 ? do somehting : do some other thing – Reza Shoja Jun 24 '19 at 12:08
  • `console.log(this.state.clients)` returns an empty array, and after it renders it returns the correct array of clients. `console.log(typeof this.state.clients)` returns `object` –  Jun 24 '19 at 12:14
  • so this is the problem! you can't iterate over an object with .map!!! read this: https://stackoverflow.com/questions/921789/how-to-loop-through-a-plain-javascript-object-with-the-objects-as-members – Reza Shoja Jun 24 '19 at 12:20
  • 1
    @BlueTurtle FYI both [] & {} will return `object` if you do `typeof []` OR `typeof {}` – Shailesh Rathod Jun 24 '19 at 12:40
  • Now @DariusBiro can you please post here what you will get after `console.log(this.state.clients)`, you can post dummy but similar data response here. – Shailesh Rathod Jun 24 '19 at 12:43

1 Answers1

1

Remember that you have to pass a function to array.map and a function can't have a statement like <Picker.Item label={client.name} value={client.id} />;. You should add a return statement before. Below is the correct one:

<Picker
    style={{ width: "100%" }}
    mode="dropdown"
    selectedValue={move.client}
    onValueChange={this.handleChange("client")}
>
    {this.state.clients !== "" ? (
        this.state.clients.map(client => {
            return <Picker.Item label={client.name} value={client.id} />;
        })
    ) : (
        <Picker.Item label="Loading..." value="0" />
    )}
</Picker>

And also, there seems to be a confusion with this.state.clients !== "" (Saw your comments above and thought of answering it). You can compare it with how you have initialized this.state inside constructor(props) function inside your class.

for eg:

if your code is like:

constructor(props){
    super(props);
    this.state={clients:{}};
}

then you should:

{this.state.clients !== {} ? (<Picker.Item />):(<Picker.Item label='loading' />)}

or if your code is like:

constructor(props){
    super(props);
    this.state={clients:''};
}

then you should:

{this.state.clients !== '' ? (<Picker.Item />):(<Picker.Item label='loading' />)}
Nandu Kkd
  • 332
  • 2
  • 12