Search code examples
javascriptreactjsarraysreduxaction

Display array elements from array of objects using the index obtained from another mapped array


As title suggest, I am trying to get object from an array using the index obtained from another separate array. I get error: Uncaught TypeError: venues[index].map is not a function.

venues = [
     {id: 4, title: "bro"}, {id: 5, title: "np bro"} 
   ]
   
   cityArray = [4, 5, 5, 4, 5, 5]

Above is the venues and cityArray.

I get the index correctly. dispatches works correctly.

const Home = () => {
    const { city } = useParams();
  
    const featured = useSelector((state) => state.featuredList.featured);
   
    const venues = useSelector((state) => state.venueList.venues);

    useEffect(() => {   
        dispatch(listVenues())
    }, [dispatch])


    useEffect(() => {
        dispatch(listFeatured())
    }, [dispatch])

  
    useEffect(() => {
        if (city === "perth") {
           setCityArray(featured?.featured_perth)
        }
    }, [featured, city]) 
    
    return (
        <GridWrapper>
            {cityArray?.map((i) => {
                 var index = venues?.findIndex(ar => parseInt(ar.id) === i);
                     return (
            
                        <div>
                          {venues[0].map(arr => 
                              (
                                <div>
                                   <h1>{arr.title}</h1>
                                </div>
                               )
                           )}
                        </div>    
                            )   
                        }
                            
                        
                        )}
        </GridWrapper>
    )
}

export default Home;

Solution

  • Your error Uncaught TypeError: venues[index].map is not a function is because venues[index] refers to an object not an array and objects don't implement a map method.

    If you want to continue looking up each object individually, you can simply use find() instead of findIndex() to return the object itself. (You should probably be accounting for elements that aren't found as well).

    return (
      <GridWrapper>
        {cityArray?.map((i) => {
          var venue = venues?.find((ar) => parseInt(ar.id) === i);
          return (
            <div>
              <h1>{venue.title}</h1>
            </div>
          );
        })}
      </GridWrapper>
    );
    

    But if you're going to be doing this repeatedly you should create a Map or object indexed by id and access it directly.

    const venues = [
      { id: 4, title: "bro" },
      { id: 5, title: "np bro" }
    ];
    const cityArray = [4, 5, 5, 4, 5, 5];
    
    const venueMap = new Map(venues.map(v => [v.id, v]));
    
    return (
      <GridWrapper>
        {cityArray?.map((id) => {
          const venue = venueMap.get(id);
          return (
            <div>
              <h1>{venue.title}</h1>
            </div>
          );
        })}
      </GridWrapper>
    );