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