неопределенный не является функцией (рядом с ‘….data.map ….’) | React native

#reactjs #react-native #api #geolocation

#reactjs #react-native #API #геолокация

Вопрос:

Я новичок в React native и пытаюсь разрушить ответ json, который я получил от моего вызова API, используя функцию map, и каким-то образом он выдает мне указанную выше ошибку. Я хочу отобразить aqi и доминирующие загрязнители, используя текстовый компонент. Я использую API AQICN.

 import React,{ useState , useEffect} from 'react';
import { StyleSheet, Text, View ,ActivityIndicator, ScrollView,FlatList} from 'react-native';
import * as Location from 'expo-location';


export default function HomeScreen({navigation}) {

  const [location, setLocation] = useState(null);
  const [errorMsg, setErrorMsg] = useState(null);
  //Lat and Long

  const [latitude, setLatitude] = useState(null);
  const [longitude , setLongitude]= useState(null);
  const [data, setData] = useState([]);

  const [loader, setLoader]=useState(true);


  useEffect(() => {
    (
      async () => {
      let { status } = await Location.requestPermissionsAsync();
      if (status !== 'granted') {
        setErrorMsg('Permission Denied');
        return;
      }

      let location = await Location.getCurrentPositionAsync({});
      setLocation(location);
      //Changes
      setLatitude(location.coords.latitude);
      setLongitude(location.coords.longitude);

      const la=latitude;
      const lo=longitude;
      
      async function AqicnApiCall() {
        
          let res = await fetch("https://api.waqi.info/feed/geo:"  latitude  ";"  longitude  "/?token=ac3a71fc80931abd95ede14c2040f0678f578703")
        .then((response) => response.json())
        .then((json) => setData(json.data))
        .catch((error) =>console.log(error))
         
        }    
        
        AqicnApiCall();
            
    })();
  }, [latitude, longitude]);


    //const obj=JSON.stringify(data);
    
    


    return (
    <ScrollView style={styles.container}>
        
        {
          data.map((d) =>{
            console.log(d);
            return(
              <Text style={styles.container}>{d.data.aqi}</Text>
            )
          })
        }
    </ScrollView>
  );
}





   const styles= StyleSheet.create({
     container: {
       padding:20,
       marginTop:15,
       margin:10,

     },
     paragraph : {
       padding:20,
       marginTop:5,
     }


   });
 

Это ответ API, мне нужен доминирующий загрязнитель и aqi.

введите описание изображения здесь

Комментарии:

1. Являются ли данные массивом или объектом? Кажется, это объект. Я ошибаюсь?

2. Мой плохой. Это объект. Не могли бы вы меня направить? Я пробовал другие способы, которые не работают.

Ответ №1:

Рабочее приложение: закуска на выставке

введите описание изображения здесь

Доступ aqi и dominentpol как показано ниже:

  return (
    <ScrollView style={styles.container}>
      <Text style={styles.container}>AQI: {data?.aqi}</Text>
      <Text style={styles.container}>
        Dominant Pollutant: {data?.dominentpol}
      </Text>
    </ScrollView>
  );
}

 

Полный рабочий код:

 import React, { useState, useEffect } from 'react';
import {
  StyleSheet,
  Text,
  View,
  ActivityIndicator,
  ScrollView,
  FlatList,
} from 'react-native';
import * as Location from 'expo-location';

export default function HomeScreen({ navigation }) {
  const [location, setLocation] = useState(null);
  const [errorMsg, setErrorMsg] = useState(null);
  //Lat and Long

  const [latitude, setLatitude] = useState(null);
  const [longitude, setLongitude] = useState(null);
  const [data, setData] = useState([]);

  const [loader, setLoader] = useState(true);

  useEffect(() => {
    (async () => {
      let { status } = await Location.requestPermissionsAsync();
      if (status !== 'granted') {
        setErrorMsg('Permission Denied');
        return;
      }

      let location = await Location.getCurrentPositionAsync({});
      setLocation(location);
      //Changes
      setLatitude(location.coords.latitude);
      setLongitude(location.coords.longitude);

      const la = latitude;
      const lo = longitude;

      async function AqicnApiCall() {
        let res = await fetch(
          'https://api.waqi.info/feed/geo:'  
            latitude  
            ';'  
            longitude  
            '/?token=ac3a71fc80931abd95ede14c2040f0678f578703'
        )
          .then((response) => response.json())
          .then((json) => {
            console.log('data: ', json.data);
            setData(json.data);
          })
          .catch((error) => console.log(error));
      }

      AqicnApiCall();
    })();
  }, [latitude, longitude]);

  //const obj=JSON.stringify(data);

  return (
    <ScrollView style={styles.container}>
      <Text style={styles.container}>AQI: {data?.aqi}</Text>
      <Text style={styles.container}>
        Dominant Pollutant: {data?.dominentpol}
      </Text>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 20,
    marginTop: 15,
    margin: 10,
  },
  paragraph: {
    padding: 20,
    marginTop: 5,
  },
});
 

Комментарии:

1. Большое вам спасибо, кетан. Не могли бы вы помочь мне в другом вопросе? API также возвращает iqai, который содержит имена загрязняющих веществ с их значениями, я пытался получить к нему доступ с помощью функции map, но она не работает. Не могли бы вы помочь?

2. Могу ли я узнать, почему ответ отклонен даже после решения проблемы, упомянутой OP?

3. Этого не понял. Я принял ответ, и код работает.

Ответ №2:

Я думаю, что некоторые из общих данных не определены или равны нулю. Пожалуйста, попробуйте это.

 <ScrollView style={styles.container}>
    
    {
      data amp;amp; data.map((d) =>{
        console.log(d);
        return(
          <Text style={styles.container}>{d?.data?.aqi}</Text>
        )
      })
    }
</ScrollView>
    
 

Комментарии:

1. Не сработало. Извините, что поздно упомянул, что данные — это объект json, а не массив.

Ответ №3:

Поскольку данные не являются массивом, и я вижу, что вы просто хотите отобразить aqi значение,

 <ScrollView style={styles.container}>
    <Text style={styles.container}>{data?.aqi}</Text>
</ScrollView>
 

На скриншоте кажется, что вы можете только выполнять итерации data.attributions .

 <ScrollView style={styles.container}>
    {data.attributions.map(attr => <Text>{attr.something}</Text>}
</ScrollView>
 

Комментарии:

1. данные ? .aqi работает нормально. Но для функции map выдает ошибку TypeError: undefined не является объектом (вычисление ошибки ‘data.iaqi.map’).

2. да, потому что опять data.iaqi -таки это не массив, а объект