Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: Object have keys, but Object.keys returns empty

enter image description here

I have an object, as you can see in picture, when i console.log() it, in first row it says course is an array of 0 length. when i expand it, it says length is 1, when i do course.length it says 0. Object.keys(course).length also says 0.

What i do in my app is, I have a listview. each item on listview is expandable. each item is a container, and each container have courses. i got containers and courses from remote server. everything was working perfectly. now i'm trying to load data from local database. it's not working anymore...

Please see my simplified code :

export default class Main extends Component{
  constructor(props) {
    super(props);
    this.state = {
      dataSource: new ListView.DataSource({
              rowHasChanged: (row1, row2) => row1 !== row2,
            })
    };
  }
  
  componentWillMount(){
    this.fetchData();
  }
  
  fetchData(){
    let data = fetch..... //// fetches data
    let dsource = {};
    
    for(let i=0; i < data.containers.length; i++){
      let container = data.containers[i];
      dsource[i] = {
        containerId: containder.id,
        course: [],
      }
      for(let x=0; x < container.courses.length; x++){
         let course = container.courses[x];
        dsource[i].course.push({
          courseId: course.id,
          courseName: course,name
        });
      }
     }
    
    this.setState({
      dataSource: this.state.dataSource.cloneWithRows(dsource)
    });
    
  }

I read lots of questions on stackoverflow, many articles, but no successs :( Object.keys(Obj).length Obj.length all returns 0. Some says because Obj.length will only show enumerable properties. i tried adding enumerable properties to object with Object.defineproperty but no changes.

any solutions? any help is highly appreciated.

The whole code (react native) :

"use strict";

import React, {Component, PropTypes} from 'react';
import {
  ActivityIndicator,
  ListView,
  StyleSheet,
  Text,
  View,
  Image,
  NetInfo,
  AlertIOS,
  TouchableOpacity,
  ScrollView,
  Dimensions,
} from 'react-native';

let SQLite = require('react-native-sqlite-storage');
let Loading = require("./Loading");
let Accordion = require('react-native-accordion');
let DeviceInfo = require('react-native-device-info');
import Icon from 'react-native-vector-icons/Ionicons';
import { Actions } from 'react-native-router-flux';
import I18n from 'react-native-i18n';
import translations from './translations';
I18n.fallbacks = true;
let LOADING = {};
import CodePush from "react-native-code-push";
let { width, height } = Dimensions.get('window');
let db = SQLite.openDatabase({name : "oc.db", location: 'default'});

export default class Courses extends Component {
  constructor(props) {
        super(props);
        this.state = {
            isLoading: false,
            dataSource: new ListView.DataSource({
              rowHasChanged: (row1, row2) => row1 !== row2,
            }),
            isConnected: true,
            dataLoaded: 0,
            restartAllowed: true
        };
    }

    toggleAllowRestart() {
      this.state.restartAllowed
        ? CodePush.disallowRestart()
        : CodePush.allowRestart();

      this.setState({ restartAllowed: !this.state.restartAllowed });
    }

    sync() {
    CodePush.sync(
      {
        installMode: CodePush.InstallMode.IMMEDIATE,
        updateDialog: false
      },
    );
  }

  componentWillMount() {
    NetInfo.isConnected.fetch().then(isConnected => {
      this.setState({
        isConnected: isConnected
      });
    });

    NetInfo.isConnected.addEventListener(
      'change',
      isConnected => {
        this.setState({
          isConnected: isConnected
        });
      }
    );

    this.fetchData();
    this.sync();
  }
    componentWillReceiveProps() {
      this.fetchData();
      this.setState({
        keyForCourse: Date()
      });
      if(this.props.goto == 'register'){
        Actions.register({type: 'reset'});
      }
    }

  fetchData() {
    console.log('Courses: fetchData running');
    if(this.state.isConnected == 'wifi' || this.state.isConnected == 'cell' || this.state.isConnected == 'true' || this.state.isConnected){
        this.setState({
          isLoading: true,
        });
        db.transaction((tx) => {
            tx.executeSql("SELECT * FROM users WHERE active=?",['yes'], (tx, results) => {
                let len = results.rows.length;
                let row = results.rows.item(0);
                let userName = row.userName;
                let userMail = row.userMail;
                let userId = row.userId;
                ///// Getting courses list
                db.transaction((tx) => {
                      tx.executeSql("SELECT * FROM containersC WHERE userId=?",[userId], (tx, results) => {
                          let dsource = {};
                          let len = results.rows.length;
                          if(len > 0){
                            for(let ind = 0; ind < len; ind++ ){
                              let cntr = results.rows.item(ind);
                              dsource[ind] = {
                                  nid: cntr.nid,
                                title: cntr.title,
                                course: [],
                                courses: {},
                              };
                              //// Get courses for each container
                              db.transaction((tx) => {
                                    tx.executeSql("SELECT * FROM courses WHERE userId=? AND container_nid=?",[userId, cntr.nid], (tx, results) => {
                                        let lenc = results.rows.length;
                                        if(lenc > 0){
                                            for(var j=0; j < lenc; j++){
                                              let crs = results.rows.item(j);
                                              console.log('Course:', crs);
                                              dsource[ind].course.push({
                                                course_id: crs.course_id,
                                                title: crs.title,
                                                cost: crs.cost,
                                                status: crs.status,
                                                period: crs.period // .time_sys
                                              });

                                              dsource[ind].courses[j] = {
                                                course_id: crs.course_id,
                                                title: crs.title,
                                                cost: crs.cost,
                                                status: crs.status,
                                                period: crs.period // .time_sys
                                              };
                                            }
                                            dsource[ind].total = lenc;
                                          }
                                        }, function(){
                                        console.log('Courses: Something went wrong Line 142');
                                      });
                                  });
                              //// End getting courses for containers
                            }
                            this.setState({
                              dataSource: this.state.dataSource.cloneWithRows(dsource),
                              isLoading: false,
                              dataLoaded: len
                            });
                          }
                        }, (err)=>{
                          console.log('Courses: Something went wrong', err);
                        });
                    }
                );
                //// End getting courses list
              }, function(){
                console.log('Courses: Unable to select users from database');
              });
          });
      } else {
        AlertIOS.alert(
          I18n.t("no_connection_title"),
          I18n.t("no_connection_desc")
        );
      }
    }

  selectRow(d, n) {
    Actions.cdetails({cid: d, tit: n});
    //Actions.rdetails({cid: d, tit: n});
  }

  renderRow(data) {
    let header = (
      <View style={{ backgroundColor: '#fff', margin: 7, marginBottom: 0 }}>
          <View style={styles.rowContainer}>
            <View  style={styles.textContainer}>
              <Icon name="ios-arrow-up" color="#00a2dd" size={30}></Icon>
              <Text style={styles.title}>{data.title}</Text>
            </View>
          </View>
    </View>
    );
    let headerOpen = (
      <View style={{ backgroundColor: '#fff', margin: 7, marginBottom: 0 }}>
          <View style={styles.rowContainer}>
            <View  style={styles.textContainer}>
              <Icon name="ios-arrow-down" color="#00a2dd" size={30}></Icon>
              <Text style={styles.title}>{data.title}</Text>
            </View>
          </View>
          <View style={styles.separator}></View>
    </View>
    );
///////////
    let cid = [];
    let content = [];
    let cll = data.total;
    console.log('Data to render :', data);
    console.log('Courses to render :', data.course);
    for(let x=0; x < cll; x++){
      cid[x] = data.course[x].course_id;
      let courseCost;
      switch(data.course[x].cost){
        case 0:
        courseCost = I18n.t("course_fee_free");
        break;
        case 1:
        courseCost = data.course[x].cost;
        break;
      }
      content.push(
        <TouchableOpacity key={cid[x]} onPress={()=>{this.selectRow(data.course[x].course_id, data.course[x].title)}} >
        <View style={[styles.cardContainer, {marginBottom: 5}, x == 0 ? { paddingTop: 6, } : {}, x == (cll+1) ? { marginBottom: 3} : {}]} key={cid[x]} >
          <View style={styles.card}>
            <View resizeMode="cover" style={styles.cardTitleContainer}>
              <Text style={styles.cardTitle}>{data.course[x].title}</Text>
            </View>
            <View
            style={{
                padding : 15,
              }}
              >
              <Text style={styles.cardContent}>
                <Icon name="ios-calendar" color="#00a2dd" size={10}> {data.course[x].period}</Icon>{'\n'}
                <Icon name="ios-pricetag" color="#00a2dd" size={10}> {courseCost}</Icon>
              </Text>
            </View>
          </View>
        </View>
        </TouchableOpacity>
      );
    }
    let clist = (
      <ScrollView style={styles.scrollView}>
      <View style={{
        padding: 6,
        paddingBottom: 0,
        borderTopColor: '#fff',
        backgroundColor: '#fff',
        margin: 7,
        marginTop: 0,
      }}>{content}</View>
      </ScrollView>
    );
////////////
  return (
    <Accordion
      header={header}
      headerOpen={headerOpen}
      content={clist}
      easing="easeOutCubic"
      underlayColor="#ebebeb"
    />
  );
  }

  render() {
    let content= null;
    if(this.state.isLoading){
      content = <Loading/>;
    } else {
      if(this.state.dataLoaded < 1){
      content = <View style={styles.errorContainer}>
     <View style={styles.error}>
     <Text style={styles.Errortext}>
      {I18n.t("courses_no_course_available")}
      </Text>
      </View>
     </View>;
      } else {
      content = <View style={{
        flex: 1
      }}>
      <ListView
        dataSource={this.state.dataSource}
        renderRow={this.renderRow.bind(this)}
      />
      </View>;
    }
    }

    return (
      <View style={styles.container}>
      {content}
      </View>
    );
  }
}

let styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "white",
    flexDirection: "column",
    justifyContent: "center",
    backgroundColor: '#e4e7ea',
  },
  separator: {
    height: 1,
    backgroundColor: "#d0d1d3",
  },
  scrollSpinner: {
    marginVertical: 20,
  },
  cardContainer:{
    flex: 1,
    alignItems: 'stretch',
    paddingLeft: 6,
    paddingRight: 6,
    borderColor: '#d0d1d3',
    borderWidth: 1,
    borderRadius: 5
  },

  card:{
    flex: 1,
    backgroundColor: '#ffffff',
    borderRadius: 2,
    borderColor: '#ffffff',
    borderWidth: 1,
    /*shadowColor: 'rgba(0, 0, 0, 0.12)',
    shadowOpacity: 0.8,
    shadowRadius: 2,
    shadowOffset: {
      height: 1,
      width: 2,
    },
    */
  },
  cardTitleContainer:{
    flex: 1,
    height: 35,
  },
  cardTitle:{
    position: 'absolute',
    top: 5,
    left: 5,
    backgroundColor: 'transparent',
    padding: 10,
    fontSize: 12,
    color: '#4c4b4b',
    fontWeight: 'bold',
  },
  rowContainer: {
    flexDirection: 'column',
    padding: 5,
  },
  textContainer: {
    flexDirection: 'row',
    flex: 1,
    padding: 5
  },
  title: {
    paddingTop: 7,
    paddingLeft: 5,
    color: '#00a2dd'
  },
  errorContainer: {
    flex: 1,
    flexDirection: "column",
    backgroundColor: '#e4e7ea',
    alignItems: 'center',
  },
  error: {
    marginTop: 75,
    width: width -150,
    height: 100,
    borderRadius: 15,
    backgroundColor: '#ecebeb',
    alignItems: 'center',
    justifyContent: 'center',
  },
  Errortext: {
    color: '#757575'
  },
});

Courses = CodePush(Courses);
like image 722
Ata Mohammadi Avatar asked Oct 11 '16 15:10

Ata Mohammadi


People also ask

What does object keys return JavaScript?

Object.keys() returns an array whose elements are strings corresponding to the enumerable properties found directly upon object . The ordering of the properties is the same as that given by looping over the properties of the object manually.

What does an empty object return in JavaScript?

Checking empty object with JavaScript It will return false and not throw a TypeError .

Is Empty object false in JavaScript?

There are only seven values that are falsy in JavaScript, and empty objects are not one of them. An empty object is an object that has no properties of its own. You can use the Object. keys() function to check if an object is empty as shown below.

Is object empty JavaScript?

Use Object. keys will return an array, which contains the property names of the object. If the length of the array is 0 , then we know that the object is empty. We can also check this using Object. values and Object.


2 Answers

Try this,

 const keys =[];  
    const person = {
    name : 'Jobelle',
    age :22,
    mob :8547391599
    }
    
    Object.getOwnPropertyNames(tempObj).forEach(prop => {
              keys.push(prop);
            });
like image 57
Jobelle Avatar answered Sep 22 '22 15:09

Jobelle


There are 3 factors that can cause the general behavior you describe. In your case, I think it's the first:

  1. When you invoke console.log(x), the Chrome console will show a summary of the object x at the time. However, when you expand the object, the value is obtained again. The detailed object you see may have changed since the call to console.log(), and changes will appear in the detail.

  2. Properties may belong to an object's prototype (as opposed to "own" properties):

    > x = {a:1}
    { a: 1 }
    > y = Object.create(x)
    > y.a
    1
    > y
    {}
    > Object.keys(y)
    []
    
  3. Properties may be non-enumerable, and won't show up in key listings. length is a non-enumerable property.

like image 44
slezica Avatar answered Sep 19 '22 15:09

slezica