Skip to content
Advertisement

How do I convert React API data to props for use in other components?

I’ve been stuck on this for awhile now and I can’t wrap my head around what I need to do with this data to be able to use it in other components. I’m able to render the data as expected but others tell me to construct the data in a function to be able to call it as props like props.name or props.whatever. But my issue is also that the API data doesn’t classify by text like name, but rather by id’s.

{
  "data": [
    {
      "3": {
        "value": 177
      },
      "6": {
        "value": "2220 Three Kings "
      },
      "40": {
        "value": "In Progress"
      },
      "80": {
        "value": 38295.47

So whenever I tried to use this method I get errors. I’m also unsure on how to actually change my code to assign each field to it’s own prop like title or amount. I’ve tried researching all over and haven’t had any luck.

Here is my API call that is currently rendering data:

import React, { Component } from 'react'

let headers = {
  'QB-Realm-Hostname': 'XXXXXXXXXXXXX.quickbase.com',
  'User-Agent': 'FileService_Integration_V2.1',
  'Authorization': 'QB-USER-TOKEN XXXXX_XXXX_XXXXXXXXXXXXXXXXXXXXXXXXXX',
  'Content-Type': 'application/json'
};

class JobsTableApi extends Component {
  constructor(props) {
    super(props);

    this.state = {
      data: null,
    };
  }

  componentDidMount() {
    this.fetchData();
  }    

  fetchData = () => {    
     let body = {"from":"bpz99ram7","select":[3,6,80,81,82,83,86,84,88,89,90,91,92,93,94,95,96,97,98,99,101,103,104,105,106,107,109,111,113,115,120,123,224,225,226,227,228,229,230,231,477,479,480,481],"where": "{40.CT. 'In Progress'}","sortBy":[{"fieldId":6,"order":"ASC"}],"groupBy":[{"fieldId":40,"grouping":"equal-values"}],"options":{"skip":0,"top":0,"compareWithAppLocalTime":false}}

    fetch('https://api.quickbase.com/v1/records/query', {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(body)
    }).then(response => response.json())
      .then( data => this.setState({ data })
      );
    }

  render() {
    const { data } = this.state;

      if (data === null) return 'Loading Job Data...  ';

    return (
      <ul>
        {Object.keys(data["data"]).map(item => 
          <div key = {item.id}>
            <h2>
              Id: {data["data"][item][3].value} -- {data["data"][item][6].value}
              <br />
              {data["data"][item][40].value}
            </h2>
            <h5>Overall Project Totals:</h5>
              <p>Adj Contract Amount: ${Math.round(data["data"][item][80].value)}</p>
              <p>Design Hours: {Math.round(data["data"][item][88].value)},</p>
              <p>Design Amount: ${Math.round(data["data"][item][91].value)},</p>
              <p>SubRough Hours: {Math.round(data["data"][item][92].value)},</p>
              <p>SubRough Amount: ${Math.round(data["data"][item][95].value)},</p>
              <p>Rough Hours: {Math.round(data["data"][item][96].value)},</p>
              <p>Rough Amount: ${Math.round(data["data"][item][98].value)},</p>
              <p>Finish Hours: {Math.round(data["data"][item][104].value)},</p>
              <p>Finish Amount: ${Math.round(data["data"][item][107].value)},</p>
              <p>Close Hours: {Math.round(data["data"][item][477].value)},</p>
              <p>Close Amount: ${Math.round(data["data"][item][480].value)},</p>
              <p>CURRENT/ACTUAL Hours: {Math.round(data["data"][item][479].value)},</p>
              <p>CURRENT/ACTUAL Amount: ${Math.round(data["data"][item][224].value)}</p>
          </div>
        )}
      </ul>
    )
  }
}

export default JobsTableApi;

Any help or suggestions on How I can use this data, move it over to props with the numeric ID’s and be able to call these fields on my other components would be greatly appreciated.

My idea is that I already have other components that have line charts for areas that I just want to populate with these fields that I’m already getting with this code, I just don’t know how to convert to props with Id’s and be able to use that in my other components.

UPDATE: I’ve attempted this multiple times and either get nothing to render, or errors that props or data is undefined. I also console.log(props) and see caller , callee , and arguments properties may not be accessed on strict mode functions or the arguments objects for calls to them. I’ve moved the API call file directly under src, and my Title.js file where I’m trying to move the data is in src>components>header>Title.js.

Title.js:

import { React, Component } from 'react'
import '../../JobsTableApi';

class Title extends Component {
  constructor(props) {
    super(props);
    console.log(props)
  }

  render() {
    return (
      <h1>
      {Object.keys(this.props.data["data"]).map(item => 
        <div key = {item.id}>
          <h1>
            {this.props.name}
          </h1>
        </div>
        )
      }
      </h1>
    )
  }
}

export default Title

API Call:

import React, { Component } from 'react'
import Title from './components/header/Title.js'

let headers = {
  'QB-Realm-Hostname': 'XXXXXXXXXXXX.quickbase.com',
  'User-Agent': 'FileService_Integration_V2.1',
  'Authorization': 'QB-USER-TOKEN XXXX_XXXX_XXXXXXXXXXXXXXXXX',
  'Content-Type': 'application/json'
};

class JobsTableApi extends Component {
  constructor(props) {
    super(props);

    this.state = {
      data: null,
    };
  }

  componentDidMount() {
    this.fetchData();
  }    

  fetchData = () => {    
     let body = {"from":"bpz99ram7","select":[3,6,80,81,82,83,86,84,88,89,90,91,92,93,94,95,96,97,98,99,101,103,104,105,106,107,109,111,113,115,120,123,224,225,226,227,228,229,230,231,477,479,480,481],"where": "{40.CT. 'In Progress'}","sortBy":[{"fieldId":6,"order":"ASC"}],"groupBy":[{"fieldId":40,"grouping":"equal-values"}],"options":{"skip":0,"top":0,"compareWithAppLocalTime":false}}

    fetch('https://api.quickbase.com/v1/records/query', {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(body)
    }).then(response => response.json())
      .then( data => this.setState({ data })
      );
    }

  render() {
    const { data } = this.state;

      if (data === null) return 'Loading Job Data...  ';

    return (
      <ul>
        {Object.keys(data["data"]).map(item => 
          <div key = {item.id}>
            <h2>
              <Title name={this.state["data"][item][6].value} /> -- Id: {data["data"][item][3].value} 
              <br />
            {data["data"][item][40].value}
            </h2>
            <h5>Overall Project Totals:</h5>
              <p>Adj Contract Amount: ${Math.round(data["data"][item][80].value)},</p>
              <p>Design Hours: {Math.round(data["data"][item][88].value)},</p>
              <p>Design Amount: ${Math.round(data["data"][item][91].value)},</p>
              <p>SubRough Hours: {Math.round(data["data"][item][92].value)},</p>
              <p>SubRough Amount: ${Math.round(data["data"][item][95].value)},</p>
              <p>Rough Hours: {Math.round(data["data"][item][96].value)},</p>
              <p>Rough Amount: ${Math.round(data["data"][item][98].value)},</p>
              <p>Finish Hours: {Math.round(data["data"][item][104].value)},</p>
              <p>Finish Amount: ${Math.round(data["data"][item][107].value)},</p>
              <p>Close Hours: {Math.round(data["data"][item][477].value)},</p>
              <p>Close Amount: ${Math.round(data["data"][item][480].value)},</p>
              <p>CURRENT/ACTUAL Hours: {Math.round(data["data"][item][479].value)},</p>
              <p>CURRENT/ACTUAL Amount: ${Math.round(data["data"][item][224].value)}</p>
          </div>
        )}
      </ul>
    )
  }
}

export default JobsTableApi;

Advertisement

Answer

If I understand this correctly basically you want other components on your project to be able to access the state found within the JobsTableApi class component right? Since that state is the one containing the fetched data? If that is the case then just create the other components as you would eg:

class OtherComponent extends Component { constructor(props) {
super(props); } 
}

so then to access the state from other components without triggering a compile error just use the argument props so that everything looks the same as the class component but just with the added props before it for instance this is your code for the JobsTableApi:

{Object.keys(data["data"]).map(item => 
      <div key = {item.id}>

The access this on new component just use props for instance:

{Object.keys(this.props.data["data"]).map(item => 
      <div key = {item.id}>

Then the last step would be to go to your JobsTableApi and import the new component and pass props to it:

import OtherComponent from "./OtherComponent";

Then to your render method you could add it to be used around as such:

render ( return ( <OtherComponent data={this.state.data} /> ) );

Lastly you could also swap this process and instead use your JobsTableApi on the new component you would just need to lift the state to do this or in other words fetch the data on the new component instead.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement