Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
167
rated 0 times [  174] [ 7]  / answers: 1 / hits: 26974  / 8 Years ago, fri, june 10, 2016, 12:00:00

I am attempting to run a .js file that will allow me to import a JSON file into Parse.com using REST API. The issue is that when I run it I get this error:



TypeError: Cannot read property 'length' of undefined
at importFromJson


Here is the .js in its entirety. Can someone please help me out? I'm pretty new to .js and REST API, having to do this due to Parse messing up and removing import feature.



var PARSE_APPLICATION_ID = 'APPID';
var PARSE_REST_API_KEY = 'RESTKEY';

var JSON_FILE_PATH = '/Users/candacebrassfield/Documents/JacksonParse/cloud/JacksonDirectory.json'; // Path to JSON file to import
var IMPORTED_CLASS_NAME = 'JacksonDirectory2'; // Class to import
var POINTING_CLASS_NAME = 'JacksonDirectory'; // Class with pointers to imported class
var POINTING_CLASS_PROPERTY = 'String'; // Name of pointer property

var request = require('request');
var fs = require('fs');

// Import objects from JSON to Parse
importFromJson(JSON_FILE_PATH, IMPORTED_CLASS_NAME, function(newObjectIds) {
console.log('Successfully imported objects from JSON.');
// Update objects from external Parse class pointing to imported objects
updatePointingObjects(IMPORTED_CLASS_NAME, POINTING_CLASS_NAME, POINTING_CLASS_PROPERTY, newObjectIds, function() {
console.log('Successfully updated pointing objects.');
});
});


function importFromJson(jsonFilePath, importedClassName, callback) {
// Store new objectIds associated to their original objectIds
// Will be used to update pointers of other Parse classes
var newObjectIds = {};

// Read and parse JSON file
var json = JSON.parse(fs.readFileSync(jsonFilePath, 'utf8'));

// Delay requests with setTimeout to stay under Parse's limit
delayedAsyncLoop(function(i, fnCallback) {
// Loop
var obj = json.results[i - 1];
var originalObjectId = obj.objectId;
// Create object using Parse REST API
createObject(importedClassName, obj, function(newObj) {
// Abort if request fails
if (!newObj) process.exit(-1);
// Associate the object's new objectId to its original objectId
newObjectIds[originalObjectId] = newObj.objectId;
fnCallback();
});
},
json.results.length, // Iterations

100, // Delay in milliseconds
function() { // Done looping
callback(newObjectIds);
});
}

function updatePointingObjects(importedClassName, pointingClassName, pointingClassProperty, newObjectIds, callback) {
// Get all objects from another Parse class that point to our imported class
getAllPointingObjects(pointingClassName, pointingClassProperty, function(pointingObjects) {
// Abort if request fails
if (!pointingObjects) process.exit(-1);

var nbObjectsToUpdate = pointingObjects.length;
// Delay requests with setTimeout to stay under Parse's limit
delayedAsyncLoop(function(i, fnCallback) {
// Loop
var pointingObject = pointingObjects[i - 1];
var pointer = pointingObject[pointingClassProperty];
if (!pointer || pointer.className != importedClassName) {
fnCallback();
nbObjectsToUpdate--;
if (!nbObjectsToUpdate) callback(); // Done updating pointing objects
return;
}
// Retrieve the new objectId each pointer should be updated with
var originalObjectId = pointer.objectId;
var newObjectId = newObjectIds[originalObjectId];
if (!newObjectId) {
fnCallback();
nbObjectsToUpdate--;
if (!nbObjectsToUpdate) callback(); // Done updating pointing objects
return;
}
// Update pointer to the new objectId
updatePointingObject(pointingClassName, pointingClassProperty, pointingObject.objectId, importedClassName, newObjectId, function() {
fnCallback();
nbObjectsToUpdate--;
if (!nbObjectsToUpdate) callback(); // Done updating pointing objects
});
},
pointingObjects.length, // Iterations
100 // Delay in milliseconds
);
});
}


function delayedAsyncLoop (fn, iterations, delay, callback) {
(function loop (i, done) {
setTimeout(function() {
fn(i, function() {
if (--i) {
// Keep looping
loop(i, done);
} else {
// Loop done
if (done) done();
}
});
}, delay)
})(iterations, callback);
}

function createObject(className, object, callback) {
delete object.objectId;
delete object.createdAt;
delete object.updatedAt;

request({
method: 'POST',
url: 'https://api.parse.com/1/classes/' + className,
headers: {
'X-Parse-Application-Id': PARSE_APPLICATION_ID,
'X-Parse-REST-API-Key': PARSE_REST_API_KEY,
'Content-Type': 'application/json; charset=UTF-8'
},
body: JSON.stringify(object)
}, function(error, response, body) {
if (response.statusCode == 201) {
var result = JSON.parse(body);

object.objectId = result.objectId;
object.createdAt = result.createdAt;
object.updatedAt = result.updatedAt;

console.log('Created ' + className + ' object with objectId ' + result.objectId);
callback(object);
} else {
console.log('Error: ' + response.statusCode);
console.log(body);
callback();
}
});
}

function getAllPointingObjects(className, pointingProperty, callback) {
getPointingObjectsRecursive([], className, pointingProperty, 0, null, callback)
}

function getPointingObjectsRecursive(allObjects, className, pointingProperty, skipNb, minCreatedAt, callback) {
var whereObj = {};
whereObj[pointingProperty] = {
'$exists': true
};
if (minCreatedAt) {
whereObj['createdAt'] = {
'$gt': minCreatedAt
};
}
var queryString = {
'limit': 1000,
'order': 'createdAt',
'skip': skipNb,
'where': JSON.stringify(whereObj)
};

request({
method: 'GET',
url: 'https://api.parse.com/1/classes/' + className,
headers: {
'X-Parse-Application-Id': PARSE_APPLICATION_ID,
'X-Parse-REST-API-Key': PARSE_REST_API_KEY
},
qs: queryString
}, function(error, response, body) {
if (response.statusCode == 200) {
var results = JSON.parse(body).results;
Array.prototype.push.apply(allObjects, results);
if (results.length == 1000) {
// Keep fetching
if (skipNb > 10000) {
minCreatedAt = results[999].createdAt;
skipNb = 0;
}
getPointingObjectsRecursive(allObjects, className, pointingProperty, skipNb+1000, minCreatedAt, callback);
} else {
// All objects fetched
callback(allObjects);
}
} else {
console.log('Error: ' + response.statusCode);
console.log(body);
callback();
}
});
}

function updatePointingObject(pointingClassName, pointingClassProperty, pointingObjectId, pointedClassName, pointedObjectId, callback) {
var pointer = {
__type: Pointer,
className: pointedClassName,
objectId: pointedObjectId
};

var requestBody = {};
requestBody[pointingClassProperty] = pointer;

request({
method: 'PUT',
url: 'https://api.parse.com/1/classes/' + pointingClassName + '/' + pointingObjectId,
headers: {
'X-Parse-Application-Id': PARSE_APPLICATION_ID,
'X-Parse-REST-API-Key': PARSE_REST_API_KEY,
'Content-Type': 'application/json; charset=UTF-8'
},
body: JSON.stringify(requestBody)
}, function(error, response, body) {
if (response.statusCode == 200) {
console.log('Updated pointer of ' + pointingClassName + '/' + pointingObjectId + ' to ' + pointedObjectId);
callback();
} else {
console.log('Error: ' + response.statusCode);
console.log(body);
callback();
}
});
}


Here is an edited version of the JSON file.



[  

{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
},
{
TELEPHONE NUMBER:,
FAMILY NAMES:,
STREET ADDRESS:,
CITY, STATE, ZIP CODE:,
E-MAIL ADDRESS:
}
]


Those blank ones were all at the bottom of the file, but removing them didn't fix anything.


More From » json

 Answers
6

The sample JSON has no results property, so json.results is undefined.



json.length will give you the number of iterations required.



JSON.parse([{},{}]).length => 2

[#61823] Wednesday, June 8, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
agustindejonm

Total Points: 738
Total Questions: 84
Total Answers: 84

Location: Northern Ireland
Member since Mon, Nov 14, 2022
2 Years ago
agustindejonm questions
Fri, Jun 25, 21, 00:00, 3 Years ago
Fri, Sep 18, 20, 00:00, 4 Years ago
Sat, May 16, 20, 00:00, 4 Years ago
;