0

My purpose for the project is to get the data from Google Analytics API and show all the data as a list. I can get the data from API successfully. I am passing the data to another component. I can see that data is the console but when I am trying to load them into the component I am getting nothing. My first component look as below:

class TabsExample extends Component {
      constructor(props) {
       super(props);
       this.handleLoad = this.authorize.bind(this);
       this.handleProfiles = this.handleProfiles.bind(this);
       this.arr = [];
       this.state = {
        info: [],
        details: []
       }
     }

    componentDidMount() {
     window.addEventListener('load', this.handleLoad);
    }

    handleAccounts = (response) => {
     var details = response.result.items;
     console.log(response)
     this.setState({
      info: details
     });
     details.map(x => {
      gapi.client.analytics.management.webproperties.list(
        { 'accountId': x.id })
        .then(this.handleProperties)
        .then(null, function (err) {
          console.log(err);
        })
      })
     }

    handleProperties = (response) => {
      // Handles the response from the webproperties list method.
      if (response.result.items && response.result.items.length) {

      // Get the first Google Analytics account
      var firstAccountId = response.result.items[0].accountId;

      // Get the first property ID
      var firstPropertyId = response.result.items[0].id;

      // Query for Views (Profiles).
      this.queryProfiles(firstAccountId, firstPropertyId);
      //console.log(firstPropertyId)
    } else {
      console.log('No properties found for this user.');
     }
    }

    queryProfiles = (accountId, propertyId) => {
    // Get a list of all Views (Profiles) for the first property
    // of the first Account.
    gapi.client.analytics.management.profiles.list({
      'accountId': accountId,
      'webPropertyId': propertyId
    })
      .then(this.handleProfiles)
      .then(null, (err) => {
        // Log any errors.
        console.log(err);
      })
    }

     handleProfiles(response) {
    // Handles the response from the profiles list method.
    if (response.result.items && response.result.items.length) {
      // Get the first View (Profile) ID.
      var firstProfileId = response.result.items[0].id;

      // Query the Core Reporting API.
      //console.log(firstProfileId);
      //this.queryCoreReportingApi(firstProfileId);
      gapi.client.analytics.data.ga.get({
        'ids': 'ga:' + firstProfileId,
        'start-date': '30daysAgo',
        'end-date': 'today',
        'metrics': 'ga:sessions, ga:bounces, ga:users'
      })
        .then((response) => {
          // this.setState({
          //   details: [this.state.details, response]
          // })
          this.arr.push(response)
        })
    } else {
      console.log('No views (profiles) found for this user.');
    }
    }

    queryCoreReportingApi(profileID) {
     console.log(profileID);
    }

    authorize = (event) => {
    var useImmidiate = event ? false : true;
    var authData = {
      client_id: CLIENT_ID,
      scope: SCOPES,
      immidiate: useImmidiate
    };
    gapi.auth.authorize(authData, (response) => {
      gapi.client.load('analytics', 'v3').then(() => {
        //console.log(response);
        gapi.client.analytics.management.accounts.list()
          .then(this.handleAccounts);
      });
    });
    }

    render() {
    return (
      <Tabs>
        <Tab label="Accounts" >
          <div>
            <NewsList info={this.arr} />
            {this.arr}
          </div>
        </Tab>
        <Tab label="Visual Data" >
          <div>
            <h2 className='tab_headline'>Tab Two</h2>
            <div className="row">
              <div className="col-md">
                <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Pie_chart_EP_election_2004.svg/1280px-Pie_chart_EP_election_2004.svg.png"
                  alt="First"
                  className="img-thumbnail"
                  style={divHeight} />
              </div>
              <div className="col-md">
                <img src="https://confluence.atlassian.com/fisheye/files/298976800/299139805/3/1484820924815/FishEye_Charts_Page02.png"
                  alt="First"
                  className="img-thumbnail"
                  style={divHeight} />
              </div>
            </div>
          </div>
        </Tab>
        <Tab
          label="User Information"
          data-route="/home">
          <div>
            <h2 className='tab_headline'>Tab Three</h2>
          </div>
        </Tab>
       </Tabs>
      )
     }
    }

I am passing all the data to below component:

import React, { Component } from 'react';
     class newsList extends Component {
     items = (props) => {
       if(props){
           return props.info.map((prop)=>{
               return(
                   <div>{prop.result.id}</div>
               )
           })
       }
     }

     render() {
        return(
            <div>
                <ul className="collection">
                    {console.log(this.state.details)}
                </ul>
            </div>
        )
     }
      }

     export default newsList;

When I see the console log I can see the Array [ ]. At the start it is not having any data. After sometime when I click again on Array [ ] I can see that it is having 2 objects. but I cannot use these objects. How can I do this?

agm1984
  • 15,500
  • 6
  • 89
  • 113
Parth
  • 51
  • 1
  • 1
  • 11
  • how about using `componentWillReceiveProps`?? it handles render as after updating props. – kangtaku Oct 18 '17 at 00:56
  • 1
    Thank you @agm1984 with the formation of the code. – Parth Oct 18 '17 at 00:59
  • I have tried `componentWillMount()` and `componentWillReceiveProps` @kangtaku. I am having the same result. – Parth Oct 18 '17 at 01:00
  • You need to use `setState` in your success block where data is fetched. Check out this question which is almost similar to yours https://stackoverflow.com/questions/46785141/storing-nested-objects-in-react-state#comment80518864_46785141. Check out the comment section. – Nandu Kalidindi Oct 18 '17 at 03:12

1 Answers1

2

Your current implementation does not utilise your React Component's state.

At the moment, your arr value is simply attached to this, therefore, React cannot see when it changes.

Embedding your arr value within your React component's state will trigger a render() every time it is changed using this.setState(), thereby making your application responsive to changes in it's value.

See below for an example of implementation.

Init:

constructor(props) {
   super(props)
   this.state: {
     arr: []
   }
 }

Update:

this.setState({
  arr: response
})

Retrieve:

const arr = this.state.arr
Arman Charan
  • 5,669
  • 2
  • 22
  • 32
  • I am getting the data as an object now. It is good. But still, I am not able to access the data. The error I am getting is `TypeError: this.props.arr.result is undefined`. – Parth Oct 18 '17 at 01:19
  • Try `this.state.arr` instead. – Arman Charan Oct 18 '17 at 01:23
  • To clarify: React's `state` is immutable. So please do not interpret this literally. But for the sake of understanding the process: saying `this.setState({arr: response})` is equivalent to saying `this.state.arr = response`. However, in practice, setting `state` directly will not work outside of the `constructor()` method. – Arman Charan Oct 18 '17 at 01:32
  • I can display the data using the `JSON.stringify(this.props.arr.result)`. But as soon as I add `JSON.stringify(this.props.arr.result.id)` I am getting the error `TypeError: this.props.arr.result is undefined`. – Parth Oct 19 '17 at 00:12
  • That would indicate that `this.props.arr.result` is `undefined`. `this.setState()` binds variables to `this.state`, not `this.props`. – Arman Charan Oct 19 '17 at 00:30
  • I am accessing the `arr` into another component. So I have to use `this.props`. – Parth Oct 19 '17 at 00:45
  • Oook sure. My bad, the code above suggested you were just trying to access it directly via your render method. I'd recommend console.logging the `this.props.arr` value to try to figure out what's going on, and hopefully why. – Arman Charan Oct 19 '17 at 01:11