EatenApplee
EatenApplee

Reputation: 13

Mapping a nested array from JSON in react with a dropdown list

I'm making a form in my fathers website where you can submit information about your car and then you'll get an email later giving you a price offer.

Anyways, inside the form there is a select list where you can select your car make, and then there is another select list that gives the models of the selected car brand. I have a JSON file that includes car brands and their respective models, but i cannot seem to get it functioning the way i want it to. In this version of the code, the second dropdown list shows me all of the cars models in the list, and not just the selected car brands models because after several tries i cannot figure out the right code. Any help would be greatly appreciated !

here is a snippet of the JSON file carModels.json

    [
    {
      "brand": "Acura",
      "models": [
        "2.2CL",
        "2.3CL",
        "3.0CL",
        "3.2CL",
        "ILX",
        "Integra",
        "Legend",
        "MDX",
        "NSX",
        "RDX",
        "3.5 RL",
        "RL",
        "RSX",
        "SLX",
        "2.5TL",
        "3.2TL",
        "TL",
        "TSX",
        "Vigor",
        "ZDX"
      ]
    },
    {
      "brand": "Alfa Romeo",
      "models": [
        "164",
        "8C Competizione",
        "GTV-6",
        "Milano",
        "Spider"
      ]
    },
    {
      "brand": "AMC",
      "models": [
        "Alliance",
        "Concord",
        "Eagle",
        "Encore",
        "Spirit"
      ]
    },
    {
      "brand": "Aston Martin",
      "models": [
        "DB7",
        "DB9",
        "DBS",
        "Lagonda",
        "Rapide",
        "V12 Vantage",
        "V8 Vantage",
        "Vanquish",
        "Virage"
      ]
    },
    {
      "brand": "Audi",
      "models": [
        "100",
        "200",
        "4000",
        "5000",
        "80",
        "90",
        "A3",
        "A4",
        "A5",
        "A6",
        "A7",
        "A8",
        "allroad",
        "Cabriolet",
        "Coupe",
        "Q3",
        "Q5",
        "Q7",
        "Quattro",
        "R8",
        "RS 4",
        "RS 5",
        "RS 6",
        "S4",
        "S5",
        "S6",
        "S7",
        "S8",
        "TT",
        "TT RS",
        "TTS",
        "V8 Quattro"
      ]
    },
    {
      "brand": "Avanti",
      "models": [
        "Convertible",
        "Coupe",
        "Sedan"
      ]
    },
    {
      "brand": "Bentley",
      "models": [
        "Arnage",
        "Azure",
        "Brooklands",
        "Continental",
        "Corniche",
        "Eight",
        "Mulsanne",
        "Turbo R"
      ]
    }
  ]

my code

import React, { Component } from 'react'
import { Col, Button, Form, FormGroup, Label, Input, FormText, Row } from 'reactstrap'

import carModels from "./carModels"


export class carousel extends Component {

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

  handleChange = (event) => {
    this.setState({carMake: this.state.carMake = event.target.value });
    console.log(this.state.carMake)
  };


  render() {


    return (
                <div>
                   <Input className="inputBrand" type="select" name="carbrand" id="carBrand" onChange={this.handleChange}>
                     <option>Choose brand</option>
                     {carModels.map((carBrand, index) => {
                       return <option>{carBrand.brand}</option>
                     })}
                  </Input>
                  <Input className="inputBrand" type="select" name="carmodel" id="carModel">
                     <option>Choose model</option>
                     {carModels.map((carBrand, index) => {
                       return carBrand.models.map((brandModels, index) => {
                          return <option>{brandModels}</option>
                       })
                     })}
                  </Input>
                </div>

Upvotes: 1

Views: 2602

Answers (2)

Jatin Parmar
Jatin Parmar

Reputation: 2900

you should handle car selection this way

 handleChange = (event) => {
      //we are storing selected index, instead of model name
      this.setState({carMake:event.target.selectedIndex });
     console.log(this.state.carMake)
    };

and you should render car model list of selected car as

renderCarModles=()=>{
  if(this.state.carMake=='')return <option>select car </option>;
   //using selected index to fetch models
   let carModels=carModels[this.state.carMake].models;
    return carModels.map((brandModels, index) => {
                      return <option>{brandModels}</option>
                   })

}

hope this will help!

Upvotes: 0

Abhishek Kulkarni
Abhishek Kulkarni

Reputation: 1767

Try this and just apply a if condition in your map for the second dropdown:

    return (
                <div>
                   <Input className="inputBrand" type="select" name="carbrand" id="carBrand" onChange={this.handleChange}>
                     <option>Choose brand</option>
                     {carModels.map((carBrand, index) => {
                       return <option>{carBrand.brand}</option>
                     })}
                  </Input>
                  <Input className="inputBrand" type="select" name="carmodel" id="carModel">
                     <option>Choose model</option>
                     {carModels.map((carBrand, index) => {
                          if(carBrand.brand == this.state.carMake){
                              return carBrand.models.map((brandModels, index) => {
                                  return <option>{brandModels}</option>
                              })
                           }
                      })}
                  </Input>
                </div>
)

Upvotes: 1

Related Questions