VonHugenstein
VonHugenstein

Reputation: 119

React get value from key:value array

Beginner question. I know this is a simple question but I haven't been able to get this to work. I'm passing an object which holds an array of k:v pairs to a component. Eventually this props will contain multiple k:v pairs, but for now I'm just passing the one.

[{goal: 20000}]

In the component I'm trying to grab the value, 20000, so I can display it on screen. I can't seem to get just the number. If I look at props.goal I get the entire k:v.

[{goal: 20000}]

If I try props[0].goal I get 'TypeError: undefined is not an object (evaluating 'props[0].goal')'

What am I missing? Thanks for any help.

Update: Here is the entire code for the component in question.

import { React, useState } from "react";
import Form from "react-bootstrap/Form";
import { Row, Col, Button } from "react-bootstrap";
import "./../css/Goal.css";

const Goal = (props) => {
  // const [goal, setGoal] = useState("");
  const [record, setRecord] = useState("");
  const monthlyGoal = 2;

  console.log("props[0]");
  console.log(props[0]); //undefined
  console.log("props");
  console.log({ props }); //See below

props: Object

goal: Object

goals: [{goal: 20000}] (1)

  const handleInput = (event) => {
    console.log(event);
    event.preventDefault();
    setRecord(event.target.value);
    console.log(record);
  };

  const defaultOptions = {
    significantDigits: 2,
    thousandsSeparator: ",",
    decimalSeparator: ".",
    symbol: "$",
  };

  const formattedMonthlyGoal = (value, options) => {
    if (typeof value !== "number") value = 0.0;
    options = { ...defaultOptions, ...options };
    value = value.toFixed(options.significantDigits);

    const [currency, decimal] = value.split(".");
    return `${options.symbol} ${currency.replace(
      /\B(?=(\d{3})+(?!\d))/g,
      options.thousandsSeparator
    )}${options.decimalSeparator}${decimal}`;
  };

  return (
    <Form>
      <Row className="align-items-center flex">
        <Col sm={3} className="goal sm={3}">
          <Form.Control
            id="inlineFormInputGoal"
            placeholder="Goal"
            // onChange={(e) => setGoal(e.target.value)}
          />
          <Button type="submit" className="submit btn-3" onSubmit={handleInput}>
            Submit
          </Button>
        </Col>
        <Col>
          <h1 className="text-box">
            Goal: {formattedMonthlyGoal(monthlyGoal)}
          </h1>
        </Col>
      </Row>
    </Form>
  );
};
export default Goal;

Update 2:Here is the parent component:

import React, { useEffect, useState } from "react";
import Goal from "./Goal";
import axios from "axios";

const Dashboard = () => {
  const [dashboardinfo, setdashboardinfo] = useState([]);
  useEffect(() => {
    async function fetchData() {
      try {
        const data = (await axios.get("/api/goals/getgoals")).data;
        setdashboardinfo(data);
      } catch (error) {
        console.log(error);
      }
    }
    fetchData();
  }, []);

  return (
    <React.Fragment>
      <Goal dashboardinfo={dashboardinfo} />
     
    </React.Fragment>
  );
};

export default Dashboard;

Upvotes: 0

Views: 5924

Answers (3)

VonHugenstein
VonHugenstein

Reputation: 119

I believe I've resolved my issue. It wasn't so much a problem with accessing the key:value as I thought, because when the page was initialized I was able to grab the value and display it fine. However, when I refreshed the page I lost all of the props data and that resulted in an error. I tracked it down to the useState didn't seem to be updating the value before I was trying to read it. So I added a useEffect in the child component.

const Goal = (props) => {
  const [goal, setgoal] = useState([]);

  useEffect(() => {
    setgoal(props.goal);
    console.log("the goal", goal);
  }, [props.goal, goal]);

...

This seems to have worked as I'm getting the information I want and not getting any errors when I refresh. This may not be the ideal way to go about this but it is working.

Upvotes: 0

LucasStbnr
LucasStbnr

Reputation: 61

Your props contains the object "dashboardinfo" so you need to do

props.dashboardinfo.goals[0].goal

or a better way is to destructure your props object like this

const Goal = ({dashboardinfo: { goals }}) => {
  ...
  goals[0].goal
  ...
}

Upvotes: 0

Sean
Sean

Reputation: 1456

If you get an object like the following from console logging destructured props:

{
  dashboardinfo: {goals: [{goal: 20000}]}
}

You need to use props.dashboardinfo.goals[0].goal to get the value.

Upvotes: 1

Related Questions