Error in useEffect accessing API data

Asked

Viewed 57 times

1

I have the following hook that runs the API calls smoothly, returning the information and updating the components normally, but it brings some connection errors in the console, I believe these errors happen when I run the application before returning the API responses, but as I’m using async await I don’t understand why errors are occurring, someone can help me with this:

import { useEffect, useContext } from "react";
import FinancesDataService from "../services/FinancesService";
import { AppContext } from "../components/context/AppContext";

export const useDetails = () => {
  const { state, dispatch } = useContext(AppContext);
  const { selectedPeriod, profit, cost } = state;

  useEffect(() => {
    async function countTransactions() {
      const response = await FinancesDataService.countTransactions(
        selectedPeriod
      );
      dispatch({ type: "setCounter", payload: response.data });
    }
    countTransactions();

    async function getProfit() {
      const response = await FinancesDataService.getProfit(selectedPeriod);
      dispatch({ type: "setProfit", payload: response.data });
    }
    getProfit();

    async function getCost() {
      const response = await FinancesDataService.getCost(selectedPeriod);
      dispatch({ type: "setCost", payload: response.data });
    }
    getCost();

    function calcBalance(profit, cost) {
      return profit - cost;
    }
    dispatch({ type: "setBalance", payload: calcBalance(profit, cost) });
  }, [dispatch, selectedPeriod, cost, profit]);

  return {
    counter: state.counter,
    profit: state.profit,
    cost: state.cost,
    balance: state.balance,
  };
};

CONTROLLER:

const FinancesModel = require("../model/FinancesModel");

const findPeriods = async (_, res) => {
  try {
    const periods = await FinancesModel.distinct("yearMonth");
    res.send(periods);
  } catch (error) {
    res.send(error);
  }
};

const countTransactions = async (req, res) => {
  const period = req.params.period;
  try {
    const counter = await FinancesModel.countDocuments({ yearMonth: period });
    console.info(counter);
    res.send(counter.toString());
  } catch (error) {
    res.send(error);
  }
};

const getProfit = async (req, res) => {
  const period = req.params.period;
  try {
    const profit = await FinancesModel.aggregate([
      { $match: { $and: [{ yearMonth: period, type: "+" }] } },
      { $group: { _id: null, value: { $sum: "$value" } } },
    ]);
    res.send(profit[0].value.toString());
  } catch (error) {
    res.send(error);
  }
};

const getCost = async (req, res) => {
  const period = req.params.period;
  try {
    const cost = await FinancesModel.aggregate([
      { $match: { $and: [{ yearMonth: period, type: "-" }] } },
      { $group: { _id: null, value: { $sum: "$value" } } },
    ]);
    res.send(cost[0].value.toString());
  } catch (error) {
    res.send(error);
  }
};

module.exports = { findPeriods, countTransactions, getProfit, getCost };

inserir a descrição da imagem aqui

  • What is the answer to these 404 status requests? It is a valid json?

  • I was returning a string, I changed the controller to resume a json but gave the same problem

  • But is there a reason this route has 404 status (or some error status)? It is normal for the browser to print requests errors on the console.

  • I changed the post and put in the controller code. By the error you can notice that the first request called findPeriods does not give any error, but all the others that return string give error, although they are working. What comes from the bank in these three cases is number

  • The other three requests depend on the first one, if I executed in sequence I think would not give error, but since it is in a hook I believe that it tries to execute before having the parameter available. I have to think of a way for them to wait for the result of findPeriods

  • The error occurs in the HTTP request. Which code is responsible for this (which you use fetch, axios or XMLHttpRequest)? Apparently, FinancesModel.distinct uses one of these functions under the cloths and may be "swallowing the error" rather than propagating it. Since the API returns a valid response (json) with erratic HTTP status, this is logged in to the console but does not cause any difference in the application. But this can be dangerous, because if any real server error occurs, it will be swallowed instead of treated.

  • That is, if possible, show the code that calls the API and the backend code that is returning 404 with a valid response. What it looks like is that the React code itself has nothing to do with this behavior.

  • The code is all on github: https://github.com/rafaelcmd/personal-finances

  • I think it might be because I didn’t set the headers in the Axios instance: import Axios from "Axios"; export default Axios.create({ baseURL: "/api/Finances", });

Show 4 more comments

1 answer

2


I downloaded your project and tried to debug that problem. As I do not have access to the bank, the app does not starta and my diagnosis may not be 100% correct, but here we have the following possible causes:

  1. Financesrouter.js

    app.get("/counter/:period", countTransactions);
    app.get("/profit/:period", getProfit);
    app.get("/cost/:period", getCost);
    

    These routes do not match when period is an empty string, as shown in your screenshot and as I have verified to be the first request that occurs when the component mounts. Avoid call the API with this parameter blank. To check if this is true, test with a non-empty date and check if the status code is 200.

  2. The API port in your prints is 3000, commonly the port used by Create React App. However, if this were your problem, there would be another status code (437 for me). Make sure this is correct.

  • Thanks for the tip Rodrigo, I put a fixed parameter in each route and the errors disappeared. I’ll put some conditions to execute only when you have the data coming from the first requisition.

  • Good that it worked. As the problem was actually in Node/express, I will put these tags in the question.

  • 1

    Actually I didn’t change anything in Node, I only created an if in hook to only execute the requests when the parameter exists. But you better change the tags yourself.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.