Home > Software design >  (React Native) passing props with Map function undefined is not a function (near '...resturants
(React Native) passing props with Map function undefined is not a function (near '...resturants

Time:09-04

Hi i am trying to fetch data from sanity CMS and then pass it with props to my child component . but its not working. The same thing and code worked on my other screen but here I am getting an error. The data is being fetched I checked console.log but not being passed. The error is here I think,

{resturants?.map((type) => {
      return (
        <ResturantCard
          key={type._id}
          id={type._id}
          imgUrl="https://links.papareact.com/gn7"
          title={type.name}
          genre={type.genre}
          address={type._address}
          description={type.description}
          lat={type.lat}
          long={type.long}
          dishes={type.dishes}
        />
      );
    })}

The complete component code is as under

import { View, Text, ScrollView } from "react-native";
import { React, useEffect, useState } from "react";
import { ArrowRightIcon } from "react-native-heroicons/outline";
import ResturantCard from "./ResturantCard";
import client from "../sanity";

export default function FeaturedRow(props) {
  const [resturants, setResturants] = useState([]);
  useEffect(() => {
    console.log(props.id);
    client
      .fetch(
        `*[_type == "featured" && _id== $id ]{...,type[]->{
          ...,dishes[]->, type->{name}      
          },
        }[0]`,
        { id: props.id }
      )
      .then((data) => setResturants(data), console.log("date recieved"))
      .catch(console.log("No data received"));
  }, []);

  console.log(resturants);

  //console.log(props);
  return (
    <View>
      <View className="flex-row mt-4 items-center justify-between px-4">
        <Text className="font-bold text-lg">{props.title}</Text>
        <ArrowRightIcon />
      </View>
      <Text className="text-xs px-4 text-gray-500">{props.description}</Text>
      <ScrollView
        horizontal
        contentContainerStyle={{
          paddingHorizontal: 15,
          paddingBottom: 15,
        }}
        className="pt-4 pb-2"
      >
        {/* Resturant Card*/}
        {resturants?.map((type) => {
          return (
            <ResturantCard
              key={type._id}
              id={type._id}
              imgUrl="https://links.papareact.com/gn7"
              title={type.name}
              genre={type.genre}
              address={type._address}
              description={type.description}
              lat={type.lat}
              long={type.long}
              dishes={type.dishes}
            />
          );
        })}
        <ResturantCard
          id="d1"
          imgUrl="https://links.papareact.com/gn7"
          title="Ramzan Shinwari"
          genre="Dessi Food"
          address="123 Chaklala"
          description="The Best Food in the Town"
          lat="121343"
          long="453233"
          dishes={[]}
        />
        <ResturantCard
          id="d1"
          imgUrl="https://links.papareact.com/gn7"
          title="Ramzan Shinwari"
          genre="Dessi Food"
          address="123 Chaklala"
          description="The Best Food in the Town"
          lat="121343"
          long="453233"
          dishes={[]}
        />
        <ResturantCard
          id="d1"
          imgUrl="https://links.papareact.com/gn7"
          title="Ramzan Shinwari"
          genre="Dessi Food"
          address="123 Chaklala"
          description="The Best Food in the Town"
          lat="121343"
          long="453233"
          dishes={[]}
        />
      </ScrollView>
    </View>
  );
}

The Child component Code

import { View, Text, TouchableOpacity, Image } from "react-native";
import React from "react";
import { MapPinIcon, StarIcon } from "react-native-heroicons/outline";

export default function ResturantCard(props) {
  return (
    <TouchableOpacity className="bg-white shadow mr-4">
      <Image source={{ uri: props.imgUrl }} className="h-36 w-64" />
      <View className="px-3 pb-3">
        <Text className="text-lg font-bold pt-2">{props.title}</Text>
        <View className="flex-row items-center space-x-1">
          <StarIcon color="green" size={22} opacity={0.5} />
          <Text>
            {props.rating} . {props.genre}
          </Text>
        </View>
        <View className="flex-row items-center space-x-1">
          <MapPinIcon />
          <Text className="text-xs text-gray-500">Near . {props.address}</Text>
        </View>
      </View>
    </TouchableOpacity>
  );
}

The output Output of console

CodePudding user response:

The issue here is that restaurants is no longer an array after you have set the server response. It is an object. An object does not define the function map.

You can see this in your log message that restaurants is initially an empty array, but after you call setRestaurants(data) it is an object.

Judging from the object itself and the properties that you are accessing inside the render function, you actually want to access the type property of the object data. The type of the server response is an actual array. Each object inside this array defines the properties that you are accessing, i.e. name, genre, dishes...

Thus, you could change your code to the following:

then((data) => setResturants(data.type))

CodePudding user response:

These error can only occur when the resturants variable is undefined.

If i would suggest you to only set the resturants variable if data is defined.

if(data) {
  setResturants(data)
}
  • Related