Noble Polygon
Noble Polygon

Reputation: 806

Toggle component with mapped data

I'm creating a component with a view that can be opened and closed like an accordion. The data for the view comes from this JSON file:

{
  "tracks": [
    {
      "uid": "001",
      "line_number": "S123456",
      "feed": [
        {
          "line_number": "S123456",
          "outer_situation": "low",
          "departure_time": "2020-04-21T10:55Z"
        },
        {
          "line_number": "S123456",
          "outer_situation": "high",
          "departure_time": "2020-04-21T10:55Z"
        },
        {
          "line_number": "S123456",
          "departure_time": "2020-04-21T10:55Z"
        }
      ]
    },
    {
      "uid": "002",
      "line_number": "S00000",
      "feed": [
        {
          "line_number": "S123456",
          "outer_situation": "low",
          "departure_time": "2020-04-21T10:55Z"
        },
        {
          "line_number": "S123456",
          "outer_situation": "high",
          "departure_time": "2020-04-21T10:55Z"
        },
        {
          "line_number": "S123456",
          "outer_situation": "high",
          "departure_time": "2020-04-21T10:55Z"
        }
      ]
    }
  ]
}

Each "track" represents a row, so there could be unlimited numbers of rows. When my row is closed, it the map looks like this:

<div>
            {connex.map((tracks) => (
              <div
                className={style.connection_container}
                onClick={() => setShowConnections(!showConnections)}
                onKeyPress={() => setShowConnections(!showConnections)}
                role="button"
                tabIndex="0"
              >

                <div span={1}>
                </div>
                <div span={3}>
                  <div className={style.vehicle_id}>
                    <p>{tracks.line_number}</p>
                  </div>
                </div>
                <div span={6}>
                  <span className={style.location_text}>
                  {tracks.origin}
                  </span>
                  <span> - </span>
                  <span className={style.location_text}>
                    {tracks.destination}
                  </span>
                </div>
                <div span={8}>
                  <div className={style.stop_point}>
                    <p>{tracks.stop_point}</p>
                  </div>
                </div>
                <div span={6}>
                  <span className={style.stop_point}>
                    <p>{tracks.arrival_time}</p>
                  </span>
                </div>
              </div>
            ))}
          </div>

Before adding mapped JSON data, I was using with the information that would be included after I created the JSON, so the original toggle function works fine. However, now as I am trying to add a .map function inside of the opened view, I am doing something wrong in the syntax and I cannot figure out what it is. https://stackblitz.com/edit/react-lnpfvu error: JSX expressions must have one parent element.

Since I already have a condition for displaying data, is there a better way I can create this toggle component that would simplify how I access data?

Upvotes: 0

Views: 46

Answers (3)

Dev Yego
Dev Yego

Reputation: 553

Check my approach. After I figured out the multiple elements issue, I met an IndexError as you were trying to access an unknown index in the toggle-able view.

Upvotes: 0

bakar_dev
bakar_dev

Reputation: 996

Multiple childs should be wrap into a parent dive and there is no any parent div in your map function. Check the code i have added comment. Try this:

import React, { useState } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import style from './style.css'
import data from './data.json'

const App = () => {

 const [showConnections, setShowConnections] = useState(false);
  const connex = data.tracks;

    return (
        <div className={style.interchange_connections}>
      {/* default = closed */}
      {!showConnections

        ? (
          <div>
            {connex.map((tracks) => (
              <div
                className={style.connection_container}
                onClick={() => setShowConnections(!showConnections)}
                onKeyPress={() => setShowConnections(!showConnections)}
                role="button"
                tabIndex="0"
              >

                <div span={1}>
                </div>
                <div span={3}>
                  <div className={style.vehicle_id}>
                    <p>{tracks.line_number}</p>
                  </div>
                </div>
                <div span={6}>
                  <span className={style.location_text}>
                  {tracks.origin}
                  </span>
                  <span> - </span>
                  <span className={style.location_text}>
                    {tracks.destination}
                  </span>
                </div>
                <div span={8}>
                  <div className={style.stop_point}>
                    <p>{tracks.stop_point}</p>
                  </div>
                </div>
                <div span={6}>
                  <span className={style.stop_point}>
                    <p>{tracks.arrival_time}</p>
                  </span>
                </div>
              </div>
            ))}
          </div>
        )
        : (
      <>
            {/* opened view */}

                    <div>
            {connex.map((tracks) => (
               <div> {/* parent div */}
              <div
                className={style.connection_container}
                onClick={() => setShowConnections(!showConnections)}
                onKeyPress={() => setShowConnections(!showConnections)}
                role="button"
                tabIndex="0"
              >

                <div span={1}>
                </div>
                <div span={3}>
                  <div className={style.vehicle_id}>
                    <p>{tracks.line_number}</p>
                  </div>
                </div>
                <div span={6}>
                  <span className={style.location_text}>
                  {tracks.origin}
                  </span>
                  <span> - </span>
                  <span className={style.location_text}>
                    {tracks.destination}
                  </span>
                </div>
                <div span={8}>
                  <div className={style.stop_point}>
                    <p>{tracks.stop_point}</p>
                  </div>
                </div>
                <div span={6}>
                  <span className={style.stop_point}>
                    <p>{tracks.arrival_time}</p>
                  </span>
                </div>
              </div>

              // start feed data
             
              <div className={style.sub_container_wrapper}>
                <div className={style.bracket} />
                <div className={style.sub_container}>

                  <div span={1}>
                  </div>
                  <div span={2}>
                    <div className={style.vehicle_id}>
                     {tracks.feed[0].line_number} //use tracks not connex
                    </div>
                  </div>
                  </div>
              </div>
            </div> // parent div  closed
            ))}
          </div>
          </>
        )}
    </div>
    );
  }


render(<App />, document.getElementById('root'));

Upvotes: 1

ezio4df
ezio4df

Reputation: 4195

You are using multiple element without react fragment or any element in index.js line 63, try something like this,

            {connex.map((tracks) => (
              <> {/*!! here !!*/}
              <div
                className={style.connection_container}
                onClick={() => setShowConnections(!showConnections)}
                onKeyPress={() => setShowConnections(!showConnections)}
                role="button"
                tabIndex="0"
              >

                <div span={1}>
                </div>
                <div span={3}>
                  <div className={style.vehicle_id}>
                    <p>{tracks.line_number}</p>
                  </div>
                </div>
                <div span={6}>
                  <span className={style.location_text}>
                  {tracks.origin}
                  </span>
                  <span> - </span>
                  <span className={style.location_text}>
                    {tracks.destination}
                  </span>
                </div>
                <div span={8}>
                  <div className={style.stop_point}>
                    <p>{tracks.stop_point}</p>
                  </div>
                </div>
                <div span={6}>
                  <span className={style.stop_point}>
                    <p>{tracks.arrival_time}</p>
                  </span>
                </div>
              </div>

              // start feed data
              <div>
              <div className={style.sub_container_wrapper}>
                <div className={style.bracket} />
                <div className={style.sub_container}>

                  <div span={1}>
                  </div>
                  <div span={2}>
                    <div className={style.vehicle_id}>
                     {connex.feed[0].line_number}
                    </div>
                  </div>
                  </div>
              </div>
            </div>
            </> {/*!! here !!*/}
            ))}

Upvotes: 1

Related Questions