Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

I'm having a bit of a strange problem.

I need to add objects to an array, and using the normal array.push(object) doesn't seem to work (nothing is pushed).

The pushes happen both inside and outside for-loops in parse.com queries.

I've tried some debugging, and console.log on all steps return the results as I expect.

My question is: Is there something I don't know about how parse.com queries work in connection to array.push, or maybe for-loops? Any help would be appreciated.

The particulars are entities (array) and entity (object).

I'd expect a result something like:

entities = [
    { url: '/first', changefreq: 'weekly', priority: 1.0 },
    { url: '/second', changefreq: 'monthly', priority: 0.9 },
    { url: '/third', changefreq: 'weekly', priority: 0.5 }
];

But I only get the very first push to appear in the array.

I've checked all the parse.com queries, and they do return the data I need and use in the example below.

My code:

module.exports = {
  getSitemap: function(callback) {
    "use strict";
    var Page = Parse.Object.extend('Page'),
      pageQuery = new Parse.Query(Page),
      Article = Parse.Object.extend('Article'),
      articleQuery = new Parse.Query(Article),
      Profile = Parse.Object.extend('Profile'),
      profileQuery = new Parse.Query(Profile),
      Category = Parse.Object.extend('Category'),
      categoryQuery = new Parse.Query(Category),
      entities = [],
      entity = {},
      i,
      sitemap;

    entity.url = '/';
    entity.changefreq = 'weekly';
    entity.priority = 1.0;
    entities.push(entity);
    entity = {};

    articleQuery.equalTo('published', true);
    articleQuery.select("permalink");
    articleQuery.find().then(function(results) {
      for (i = 0; i < results.length; i += 1) {
        entity.url = '/article/' + results[i].get('permalink');
        entity.changefreq = 'monthly';
        entity.priority = 0.9;
        entities.push(entity);
        entity = {};
      }
    }, function(error) {
      // do nothing
    });

    pageQuery.select("pagePermaLink");
    pageQuery.find().then(function(results) {
      for (i = 0; i < results.length; i += 1) {
        entity.url = '/page/' + results[i].get('pagePermaLink');
        entity.changefreq = 'monthly';
        entity.priority = 0.7;
        entities.push(entity);
        entity = {};
      }
    }, function(error) {
      // do nothing
    });

    profileQuery.select("objectId");
    profileQuery.find().then(function(results) {
      for (i = 0; i < results.length; i += 1) {
        entity.url = '/author/' + results[i].id;
        entity.changefreq = 'monthly';
        entity.priority = 0.6;
        entities.push(entity);
        entity = {};
      }
    }, function(error) {
      // do nothing
    });

    categoryQuery.select("categoryPermaLink");
    categoryQuery.find().then(function(results) {
      for (i = 0; i < results.length; i += 1) {
        entity.url = '/category/' + results[i].get('categoryPermaLink');
        entity.changefreq = 'weekly';
        entity.priority = 0.5;
        entities.push(entity);
        entity = {};
      }
    }, function(error) {
      // do nothing
    });

    sitemap = sm.createSitemap({
      hostname: 'http://brianemilius.com',
      cacheTime: 300000,
      urls: entities
    });
    sitemap.toXML(function(err, xml) {
      if (err) {
        callback({
          error: err
        });
      }
      callback(xml);
    });
  }
};

share|improve this question
    
It might be helpful to read about JavaScript promises – See Dart 2 days ago
    
I already did and found nothing that would explain my problem. Maybe you see something I don't? – Brian Emilius 2 days ago
    
Please console.log(results). in callback.Might be you not getting the data – RIYAJ KHAN 2 days ago
    
As I wrote in the question I already did this debugging and I am getting the results I expect to get (from parse) on all steps. – Brian Emilius 2 days ago
    
Also results is not in the scope of the callback function, so it's not possible to log it there. This is one of the reasons I made an array (entities) in a parent scope, so I can transport data from one function to another. – Brian Emilius 2 days ago
up vote 2 down vote accepted

The code is starting several asynch operations then immediately taking an action that relies on their results. We need to modify the code to wait until each operation is complete.

// ...
// above here from the OP 

articleQuery.equalTo('published', true);
articleQuery.select("permalink");
// hang on to the promise
var articlePromise = articleQuery.find().then(function(results) {
  for (i = 0; i < results.length; i += 1) {
    entity.url = '/article/' + results[i].get('permalink');
    entity.changefreq = 'monthly';
    entity.priority = 0.9;
    entities.push(entity);
    entity = {};
  }
}, function(error) {
  // do nothing
});

pageQuery.select("pagePermaLink");
// hang on to the promise
var pagePromise = pageQuery.find().then(function(results) {
  for (i = 0; i < results.length; i += 1) {
    entity.url = '/page/' + results[i].get('pagePermaLink');
    entity.changefreq = 'monthly';
    entity.priority = 0.7;
    entities.push(entity);
    entity = {};
  }
}, function(error) {
  // do nothing
});

profileQuery.select("objectId");
// hang on to the promise
var profilePromise = profileQuery.find().then(function(results) {
  for (i = 0; i < results.length; i += 1) {
    entity.url = '/author/' + results[i].id;
    entity.changefreq = 'monthly';
    entity.priority = 0.6;
    entities.push(entity);
    entity = {};
  }
}, function(error) {
  // do nothing
});

categoryQuery.select("categoryPermaLink");
// hang on to the promise
var categoryPromise = categoryQuery.find().then(function(results) {
  for (i = 0; i < results.length; i += 1) {
    entity.url = '/category/' + results[i].get('categoryPermaLink');
    entity.changefreq = 'weekly';
    entity.priority = 0.5;
    entities.push(entity);
    entity = {};
  }
}, function(error) {
  // do nothing
});

// only after all of the promises that create entities are fulfilled
// do we execute the logic that relies on that data

var promises = [articlePromise, pagePromise, profilePromise, categoryPromise];
Parse.Promise.when(promises).then(function() {
    sitemap = sm.createSitemap({
      hostname: 'http://brianemilius.com',
      cacheTime: 300000,
      urls: entities
    });
    sitemap.toXML(function(err, xml) {
      if (err) {
        callback({
          error: err
        });
      }
      callback(xml);
    });
}, function(error) {
    // handle error
});
share|improve this answer
    
This did exactly what I wanted. Thanks a bunch! – Brian Emilius yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.