skip to Main Content

I am using react to create a world. I then use redux to save that world to global state in order to add a country to the world. I then use that country data to create a city inside of the country object. The issue that I am having is that I get an error when trying to add a city immediately after creating a country. The country is showing up in the redux devtools. And if I reload the page I can create a city assigned to that country without issue.

Redux slice

addCityToCreatedWorld: (state, action) => {
  const { countryPk, newCity } = action.payload;
  const countryIndex = state.createdWorld.countries.findIndex(
    (country) => country.pk === countryPk
  );
  if (countryIndex >= 0) {
    state.createdWorld.countries[countryIndex].cities.push(newCity);
  }

React Component

const handleCitySubmit = async (event) => {
  event.preventDefault();

  const data = {};
  data.name = cityName;
  data.picture = cityPicture;
  data.description = cityDescription;
  data.country = countryData.pk;

  let cityUrl = `${process.env.REACT_APP_API_HOST}/api/cities`;
  let cityFetchConfig = {
    method: "post",
    body: JSON.stringify(data),
    headers: {
      "Content-Type": "application/json",
    },
  };

  const response = await fetch(cityUrl, cityFetchConfig);
  if (response.ok) {
    const createdCity = await response.json();
    dispatch(
      addCityToCreatedWorld({
        countryPk: countryData.pk,
        newCity: createdCity,
      })
    );
    setSubmitted(true);
  } else {
    console.error(response);
  }

I have console logged the data being passed into the slice. I have console logged the data in the slice and have checked the redux dev tools.

2

Answers


  1. Chosen as BEST ANSWER

    I had to add an empty array of cities to the initial created country

    if (response.ok) {
        const createdCountry = await response.json();
        createdCountry.cities = [];
    }
    

  2. state.createdWorld.countries[countryIndex].cites is undefined, so there’s no array to push elements into. In the reducer case first grab the matched country by searching state, then check if there is a cities array and create it if necessary.

    addCityToCreatedWorld: (state, action) => {
      const { countryPk, newCity } = action.payload;
    
      const country = state.createdWorld.countries.find(
        (country) => country.pk === countryPk
      );
    
      if (country) {
        if (!country.cities) {
          country.cities = [];
        }
    
        country.cities.push(newCity);
      }
    },
    

    Better would be to add the cities array when the country is added to state in its reducer case.

    Example:

    addCountryToCreatedWorld: (state, action) => {
      const { country } = action.payload;
    
      state.createdWorld.countries.push({
        ...country,
        cities: [],
      });
    },
    addCityToCreatedWorld: (state, action) => {
      const { countryPk, newCity } = action.payload;
    
      state.createdWorld.countries.find(
        (country) => country.pk === countryPk
      )?.cities.push(newCity);
    },
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search