3

I have an array prop on a component called jobs that will show in the console, but always returns length:0

console.log screenshot

The Image you will see definitely has three elements in the array, but when I attempt to access the array length through console.log(this.props.jobs.length);

Why do the elements of this array log out, but I can't access the elements in code?

Per request from @finalfreq, see full code below:

const DepartmentContainer = React.createClass({
   getInitialState:function(){
     return{sortedJobs:{}, loaded:false};
   },
   componentDidMount:function(){
     //console.log(this.state.sortedJobs);
     var departments = this.props.departments;
     departments.map(function(name, index){
       this.state.sortedJobs[name] = [];
     }, this)

     var _this = this;

     axios.get('{api call returning json}')
     .then(function (response) {
       for(let i=0;i<response.data.jobs.length;i++){
         for(let j=0;j<response.data.jobs[i].metadata[0].value.length;j++){
           _this.state.sortedJobs[response.data.jobs[i].metadata[0].value[j]].push(response.data.jobs[i]);
         }
       }
     })
     .catch(function (error) {
       console.log(error);
     });
     //console.log(Object.keys(_this.state.sortedJobs).length);
     this.setState({sortedJobs: _this.state.sortedJobs});
     this.setState({loaded:true});
   },
   render:function(){
     var departments = this.state.sortedJobs;
     return(
       <div>
       {this.state.loaded ?
         <div className="row grid-12">
           {Object.keys(departments).map(function(label, department){
             //console.log(departments[label]);
             return <Department key={label} title={label} jobs={departments[label]}/>
           })}
         </div>
         :
         <div>Test</div>
       }
       </div>
     );
   }
 });



 const Department = React.createClass({
    getInitialState:function(){
      return{hidden:false, hasJobs:false};
    },
    componentWillMount:function(){
      const jobs = this.props.jobs;
      if(jobs.length>0){
        this.setState({hasJobs:true});
      }
    },
    componentDidMount:function(){
      console.log(this.state.hasJobs);
      console.log(this.props.jobs.length);
    },
    renderNormal:function(){
      return(
                <div className="grid-4 department-block" data-dep-filter={this.state.hidden} data-loc-filter="false" data-department={this.props.title}><h3 className="text-uppercase">{this.props.title}</h3>
                    <div className="posting-list margin-bottom">
            <h3 className="text-uppercase">{this.props.title}</h3>
                    </div>
                </div>
      )
    },
    renderEmpty:function(){
      return(
            <div className="grid-4 department-block" data-dep-filter={this.state.hidden} data-loc-filter="false" data-department={this.props.title}><h3 class="text-uppercase">{this.props.title}</h3>
                <div className="posting-list margin-bottom">
                    <div class="no-posts job-post">
                        <p><em>0 Current Openings</em></p>
                    </div>
                </div>
            </div>
      );
    },
    render: function(e){
      if (this.hasJobs) {
        return (
          this.renderNormal()
        )
      }else{
        return(
          this.renderEmpty()
        )
      }

    }
  });

In the Department:componentWillMount function I want to check the jobs array passed to it from the DepartmentContainer:render function and set the state on said Department to either hasJobs true/false

Nicholas Mann
  • 31
  • 1
  • 1
  • 4
  • 2
    are you relying on some sort of data retrieval, ie api call? The `console.log` you are showing with 0 is what it was at at the time it was first called, once data eventually populated the array the console object updates as well. – finalfreq Mar 23 '17 at 20:37
  • I am calling the following component, passing a jobs area to the prop 'jobs' return Inside the Department component I am able to log the actual array, but cannot get the array length componentDidMount:function(){ console.log(this.props.jobs.length); }, ^^ does not work, but componentDidMount:function(){ console.log(this.props.jobs); }, – Nicholas Mann Mar 23 '17 at 20:52
  • Can you post your entire code sample for the component in question? preferably you edit your original post and add it at the bottom. – finalfreq Mar 23 '17 at 20:54
  • what happens if you do `componentWillUpdate: function() { console.log(this.props.jobs.length) }` – finalfreq Mar 23 '17 at 21:00
  • I am having similar issue. You found solution to it? – Punit Makwana Aug 01 '19 at 15:48

1 Answers1

4

@finalfreq has the right idea. This is an artifact of how the JavaScript console works (for Chrome at least). Values are generally only displayed/retrieved when you expand them, which can lead to some counter intuitive behavior. You must be adding elements to the array after you are logging it to the console.

Check it out:

I make an array and push something into it. Then I log it to console. Then I push a second element.

enter image description here

Now when I expand the previous logged Array, you'll see it now has the most up-to-date values. Except "Array[1]" doesn't update to "Array[2]"... and if you push another value into the array, the previously logged values won't change even if you collapse and expand them again.

enter image description here

The moral of the story is... don't rely on console.log too much hehe. But if you do, learn its quirks.

jered
  • 11,220
  • 2
  • 23
  • 34