0

component:

  const { transactions } = useContext(GlobalContext);

  const amounts = transactions.map((transaction) => transaction.amount);

  const total = amounts.reduce((acc, item) => (acc += item), 0).toFixed(2);

the total const is throwing an error, because of toFixed

without toFixed, my numbers would concatenate as strings.

how are my numbers considered strings????????

I have try converting string to numbers with Number and parseInt. it did not work.

why are the numbers concatenating as strings?

here is the global state:

import React, { createContext, useReducer } from "react";
import AppReducer from "./AppReducer";

//Initial State
const initialState = {
  transactions: [
    {
      id: 1,
      name: "Payment to Molly Sanders",
      href: "#",
      category: "expense",
      amount: "200",
      currency: "USD",
      status: "success",
      date: "July 11, 2020",
      datetime: "2020-07-11",
    },
    {
      id: 2,
      name: "Rent",
      href: "#",
      category: "expense",
      amount: "100",
      currency: "USD",
      status: "processing",
      date: "July 1, 2020",
      datetime: "2020-07-11",
    },
    {
      id: 3,
      name: "Google",
      href: "#",
      category: "income",
      amount: "500",
      currency: "USD",
      status: "success",
      date: "July 18, 2020",
      datetime: "2020-07-18",
    },
  ],
};

//Create context
export const GlobalContext = createContext(initialState);

//Provider component
export const GlobalProvider = ({ children }) => {
  const [state, dispatch] = useReducer(AppReducer, initialState);

  return (
    <GlobalContext.Provider
      value={{
        transactions: state.transactions,
      }}>
      {children}
    </GlobalContext.Provider>
  );
};
skyboyer
  • 22,209
  • 7
  • 57
  • 64
Toan Lam
  • 109
  • 2
  • 12

2 Answers2

0

Because amount is string, change it to number and it will work.

amounts.reduce((acc, item) => (Number(acc) + Number(item)), 0).toFixed(2);
Badal Saibo
  • 2,499
  • 11
  • 23
  • or you can just add '+' before item. this will convert the string into number. Ex: `amounts.reduce((acc, item) => (acc + +item), 0).toFixed(2); ` – Tmh Jul 19 '21 at 06:58
  • 1
    @tmh You can, but that will affect code readability. – Badal Saibo Jul 19 '21 at 06:59
0

You have the type of amount as a string in your initialState that's why it's concatenating.

In JS:
Number + Number = Number
But even if either side of the + operator is String and another is a Number then the result will be a String:

String + Number = String
Number + String = String

It would be better to use the number in your initialState for all the amount. for e.g.
amount: 500 instead of amount: "500"

Or, if you have put that in for some reasons then use type cast in second step to make it look more cleaner:

 const amounts = transactions.map((transaction) => Number(transaction.amount));

The rest will be the same.

Mayank Pathela
  • 453
  • 1
  • 6
  • 15