Node.js TypeError无法读取未定义的属性objectId
Posted
技术标签:
【中文标题】Node.js TypeError无法读取未定义的属性objectId【英文标题】:Node.js TypeError Cannot read property objectId of undefined 【发布时间】:2016-06-10 16:41:51 【问题描述】:我想使用 REST API 导入 Parse.com 的 JSON 文件是:
"results": [
"TELEPHONE NUMBER":"555",
"FAMILY NAMES":"smith, john",
"objectId": "y6rwllkJhz",
"STREET ADDRESS":"555 street",
"CITY, STATE, ZIP CODE":"Town, ST 12345",
"E-MAIL ADDRESS":""
]
顺便说一句,里面有几个条目,每个条目都代表不同的家庭,为了便于阅读,我只保留了一个。
我正在使用以下 JS 尝试将其导入新类
var PARSE_APPLICATION_ID = 'APPID';
var PARSE_REST_API_KEY = 'RESTKEY';
var JSON_FILE_PATH = '/Users/path/Directory.json'; // Path to JSON file to import
var IMPORTED_CLASS_NAME = 'Directory2'; // Class to import
var POINTING_CLASS_NAME = 'Directory'; // 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.length[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();
);
问题是我收到以下错误:
TypeError: Cannot read property 'objectId' of undefined
我不明白为什么,因为它是有效的 JSON 并且 objectId 在那里。
【问题讨论】:
这里发生了太多事情。哪一行导致该错误? 您希望json.results.length[i - 1]
发生什么?因为这不是你索引数组的方式
@mrwillihog 错误是这一行,比如 35 什么的:var originalObjectId = obj.objectId;
var obj = json.results.length[i - 1];
那行没有意义。 length
应该返回一个整数 - results
的长度。我想你想做的是var obj = json.results[i - 1];
@mrwillihog 完美解决了!!谢谢!
【参考方案1】:
试试result.results[0].objectId
【讨论】:
【参考方案2】:这个作业看起来很糟糕:
var obj = json.results.length[i - 1];
.length 为您提供数组的大小。看起来您可能正在尝试对数组进行索引,并从数组中一个一个地取出每个对象。
也许它应该更像:
var obj = json.results[ json.results.length + (i - 1) ];
假设 i != 0。
【讨论】:
该错误意味着 obj 没有该属性。由于obj是从json.results分配的,所以检查var json
从JSON.parse
分配后有什么属性,然后在错误点。以上是关于Node.js TypeError无法读取未定义的属性objectId的主要内容,如果未能解决你的问题,请参考以下文章
Node.js Discord.js UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“calculatedPosition”
Node.js TypeError:无法读取未定义的属性“作者”
Node.js TypeError无法读取未定义的属性objectId
Node.js 和 jdbc:TypeError:无法读取未定义的属性“url”