skip to Main Content

Sorry, folks. I ended up summarizing too much.

Let’s go:

The current App.js is set up to display only the ‘Search’ page, as shown below. The page is wrapped within another page called ‘CallApiProvider’ because through this page, I am using API Context, which I will talk about shortly.

import React from "react";
import Search from "./src/pages/Search";
import { CallApiProvider } from "./src/components/CallApiProvider";

export default function App() {
  return (
    <CallApiProvider>
      <Search />
    </CallApiProvider>
  );
}

The idea of the ‘Search’ page is that when the app is opened, it should display a search field (the ‘Busca’ component), a movie preview (the ‘Preview’ component), and a horizontal list with the top 10 latest movies (the ‘MovieCarousel’ component).
The code for the ‘Search’ page is right below.

import React, { useContext } from "react";
import { ScrollView, FlatList, Text, ActivityIndicator } from "react-native";
import Busca from "../components/Busca";
import { EnviromentButton } from "../components/EnviromentButton";
import Preview from "../components/Preview";
import MovieCarousel from "../components/MovieCarousel";
import { ApiContext } from "../components/CallApiProvider";
import styles from "../styles/Search_styles";

function Search() {
  const { details } = useContext(ApiContext);
  if (details !== undefined) {
    console.log(details.adult);
    return (
      <ScrollView style={styles.container}>
        <Busca dica={"Type title, categories, years, etc"} />
        <FlatList
          data={details} //Precisa ser substituído pelo array de gêneros
          renderItem={({ item }) => <EnviromentButton title={item.id} active />}
          horizontal
          showsHorizontalScrollIndicator={false}
          contentContainerStyle={styles.genreList}
        />
        <Text style={styles.label}>Today</Text>
        <Preview />
        <Text style={styles.label2}> Recommend for you</Text>
        <MovieCarousel data={details} />
      </ScrollView>
    );
  } else {
    return (
      <ScrollView style={styles.container}>
        <ActivityIndicator style="large" />
      </ScrollView>
    );
  }
}

export default Search;

To load movie information, I am making an API call through the ‘CallApiProvider’ page and distributing the API response using the API Context mentioned earlier. The code for the ‘CallApiProvider’ page is right below.

import React, { useState, useEffect, createContext } from "react";
import api from "../services/api";

export const ApiContext = createContext();

export const CallApiProvider = ({ children }) => {
  const [details, setDetails] = useState(null);
  useEffect(() => {

    async function fetchDetails() {
      try {
        const { data } = await api.get("/trending/all/week?language=pt-BR");
        const limitedData = data.results.slice(0, 10);
        setDetails(limitedData);
      } catch (error) {
        console.error("Error fetching", error);
      }
    }

    fetchDetails();
  }, []);
  
  return (
    <ApiContext.Provider value={{ details }}>
      {children}
    </ApiContext.Provider>
  );
};

Therefore, my goal is that whenever the ‘Search’ page is loaded, it checks whether the ‘details’ variable has already received the API information. If it hasn’t received the information yet, it will be ‘undefined,’ and in that case, I want the loading screen to be displayed.

The problem that is happening is that instead of the ‘IF’ block rendering the loading screen when ‘details’ is ‘undefined,’ it is proceeding as if ‘details’ has the API information, causing all the code dependent on that information to break.

The error that occurs in the app is: "TypeError: Cannot read property ‘adult’ of null."
But this error shouldn’t happen if the "IF" statement worked correctly…

2

Answers


  1. Changing the answer after your update:

    The problem is because "null" is different of "undefined"
    so when you start your application for the first time the initial state of details is defined as null.
    Just clear your state here:

    from

    const [details, setDetails] = useState(null);
    

    to

    const [details, setDetails] = useState();
    

    It will solve your problem.

    For suggestion, you can change your if statement too, and use like this:

    if (details) {
    
    Login or Signup to reply.
  2. details is null not undefined

    Change details !== undefined to details or details !== null

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search