Skip to content Skip to sidebar Skip to footer

Object Has Values But Says Size Is 0 Javascript

I create an object and add properties and values to it. However, when I try to iterate through the keys it says I have a size of 0. let hash = {}; this.props.user.user.following.f

Solution 1:

You're adding to the hash object with an async function.

So, each of runs through the forEach are done asynchronously, and the evaluation of the rest of the code continues on. The block where you use the data runs before your asynchronous functions have all completed.

You should have both the code where you fetch and the code where you process data from an API call in the same asynchronous block, since, when you think about it, a block of code can't depend on asynchronous code without itself being asynchronous.

You probably want to await all of the API calls you're doing in that loop. To do so, you can use Array.prototype.map() and Promise.all().

const tweets = async () => {
  let hash = {};

  awaitPromise.all(this.props.user.user.following.map(async topicID => {
    const data = awaitAPI.graphql(graphqlOperation(queries.getTopic, { id: topicID }));
    // No need to use .then(), since we're awaiting anywaysif (data) {
      const tweedID = data.data.getTopic.post.id;
      if (!hash[tweetID]) {
        let post = data.data.getTopic.post;
        post.topics = [{
          id: data.data.getTopic.id,
          name: data.data.getTopic.name
        }]
        hash[tweedID] = post;
      } else {
        console.log("Found tweet. Appending to topics array.");
        let post = hash[tweedID];
        let topicsArr = post.topics;
        topicsArr.push({
          id: data.data.getTopic.id,
          name: data.data.getTopic.name
        });
        post.topics = topicsArr;
        hash[tweedID] = post;
      }
    }
  }));

  console.log("Hash: ", hash);
  console.log("Map size: ", Object.keys(hash).length);
  let tweets = [];
  for (const key in hash) {
    tweets.push(hash[key]);
  }
  console.log("Tweets to go into state: ", tweets);
}

tweets();

// Or, put the whole thing in brackets and call it immediately:
(async () => {
  // ...
})();

The reason that you see that the logged object has values is because of a feature of the dev-console that live-refreshes objects' properties, so they will no longer reflect the state when they've been logged, but instead display their current value.

Consider the following example:

const obj = {};
console.log(obj);
obj.foo = 'bar';

You'll see that the obj's foo property is 'bar', even though it was undefined when console.log was actually run. As @epascarello pointed out in the comments, you can tell when your browser has done this because of the little blue [i]. If you hover over it, you'll see that it says "This value was evaluated just now".

To avoid that behavior, JSON.stringify the object before logging:

const obj = {}
console.log(JSON.stringify(obj))
obj.foo = 'bar'

This will log {}, as you might expect, since it turns it into a string and spits that text out, instead of a reference to obj.

See more here.

Post a Comment for "Object Has Values But Says Size Is 0 Javascript"