When using select to specify fields and subfields, a query may fail to parse results if one of the field is null.
Steps to reproduce
1 - From the dashboard, select a collection (let say Sample) with a field typed as array (let say arrayfield).
2 - Set the field to be null.
3 - Call the following query :
new Parse.Query('Sample').select(['arrayfield.subfield']).find().then(console.log, console.error);
Expected Results
An error occurs:
Uncaught (in promise) code: undefined text: "Cannot read property 'subfield' of null"
Actual Outcome
The networking tools from Chrome shows that the server manage to answer, but the Parse JS SDK fails to parse the results. The following method fails when reading the null array. if (_obj !== undefined) { does not prevent null objects.
function handleSelectResult(data, select) {
var serverDataMask = {};
(0, _forEach.default)(select).call(select, function (field) {
var hasSubObjectSelect = (0, _indexOf.default)(field).call(field, ".") !== -1;
if (!hasSubObjectSelect && !data.hasOwnProperty(field)) {
// this field was selected, but is missing from the retrieved data
data[field] = undefined;
} else if (hasSubObjectSelect) {
// this field references a sub-object,
// so we need to walk down the path components
var pathComponents = field.split(".");
var _obj = data;
var serverMask = serverDataMask;
(0, _forEach.default)(pathComponents).call(pathComponents, function (component, index, arr) {
// add keys if the expected data is missing
if (_obj && !_obj.hasOwnProperty(component)) {
_obj[component] = undefined;
}
if (_obj !== undefined) { <----------------------------------------------- the issue is triggered after this test
_obj = _obj[component];
} //add this path component to the server mask so we can fill it in later if needed
if (index < arr.length - 1) {
if (!serverMask[component]) {
serverMask[component] = {};
}
serverMask = serverMask[component];
}
});
}
});
if ((0, _keys2.default)(serverDataMask).length > 0) {
// When selecting from sub-objects, we don't want to blow away the missing
// information that we may have retrieved before. We've already added any
// missing selected keys to sub-objects, but we still need to add in the
// data for any previously retrieved sub-objects that were not selected.
var serverData = _CoreManager.default.getObjectStateController().getServerData({
id: data.objectId,
className: data.className
});
copyMissingDataWithMask(serverData, data, serverDataMask, false);
}
}
Environment Setup
Server
parse-server version (Be specific! Don't say 'latest'.) : [4.2.0]
The server's answer:
{"results":[{"objectId":"6kYVPa22Oo","category":"CDD","organization":{"objectId":"4HCDkx2svH","createdAt":"2017-10-11T14:44:01.770Z","updatedAt":"2020-07-17T09:00:02.323Z","presentation":"","name":"La vida chula","ACL":{"gwVBuDTmy9":{"read":true,"write":true},"*":{"read":true},"role:Administrator":{"read":true,"write":true},"role:Master":{"read":true,"write":true}},"__type":"Object","className":"Organization"},"solved":false,"createdAt":"2020-06-17T12:56:19.453Z","updatedAt":"2020-07-18T12:42:27.633Z","days":4,"education":[{"degree":"BEP","domain":null}],"endingAt":{"__type":"Date","iso":"2020-06-30T00:00:00.000Z"},"equipment":[],"income":653.4,"information":"Aucune consigne spécifique pour cette mission, soyez à l'heure et donnez le meilleur de vous-même!","languages":[{"degree":"elementary","field":"en","language":{"className":"Language"}},{"degree":"elementary","field":"es","language":{"className":"Language"}},{"degree":"elementary","field":"da","language":{"className":"Language"}}],"startingAt":{"__type":"Date","iso":"2020-06-25T00:00:00.000Z"},"timeDescription":"Horaires : du lundi au mardi et du jeudi au vendredi de 10:00 à 19:00..","title":"Serveur / Serveuse petit déjeuner","toDo":"Dresser les tables","wage":15,"wagePerHour":null,"wagePerMonth":null,"level":[1,12],"place":{"objectId":"MuohKETlFl","postalCode":"75010","streetName":"Rue des Petites Écuries","streetNumber":"44","town":"Paris","createdAt":"2020-06-17T12:54:48.058Z","updatedAt":"2020-06-17T12:54:48.058Z","ACL":{"*":{"read":true},"gwVBuDTmy9":{"read":true},"role:Administrator":{"read":true,"write":true},"role:Master":{"read":true,"write":true}},"__type":"Object","className":"Place"},"skills":null}]}
The error:
Uncaught (in promise) code: undefined text: "Cannot read property 'name_fr' of null"
Issue Description
When using select to specify fields and subfields, a query may fail to parse results if one of the field is null.
Steps to reproduce
1 - From the dashboard, select a collection (let say Sample) with a field typed as array (let say arrayfield). 2 - Set the field to be null. 3 - Call the following query :
new Parse.Query('Sample').select(['arrayfield.subfield']).find().then(console.log, console.error);
Expected Results
An error occurs:
Uncaught (in promise) code: undefined text: "Cannot read property 'subfield' of null"
Actual Outcome
The networking tools from Chrome shows that the server manage to answer, but the Parse JS SDK fails to parse the results. The following method fails when reading the null array.
if (_obj !== undefined) {
does not prevent null objects.Environment Setup
Server
JS SDK
Logs/Trace
The actual request:
curl 'https://dev.bruce.work/1/classes/Mission' \ -H 'authority: xxx' \ -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36' \ -H 'content-type: text/plain' \ -H 'accept: */*' \ -H 'origin: https://xxx' \ -H 'sec-fetch-site: same-site' \ -H 'sec-fetch-mode: cors' \ -H 'sec-fetch-dest: empty' \ -H 'referer: https://xxx/app/missions/6kYVPa22Oo' \ -H 'accept-language: en-US,en;q=0.9,fr;q=0.8' \ --data-binary '{"where":{"objectId":"6kYVPa22Oo"},"keys":"category,days,education,endingAt,equipment.name_fr,income,incomeIsNet,information,languages,level,organization.name,organization.presentation,place.postalCode,place.streetName,place.streetNumber,place.town,skills,skills.name_fr,solved,startingAt,timeDescription,title,toDo,wage,wagePerHour,wagePerMonth","limit":1,"_method":"GET","_ApplicationId":"XXX","_JavaScriptKey":"XXX","_ClientVersion":"js2.14.0","_InstallationId":"XXX","_SessionToken":"r:XXX"}' \ --compressed
The server's answer:
{"results":[{"objectId":"6kYVPa22Oo","category":"CDD","organization":{"objectId":"4HCDkx2svH","createdAt":"2017-10-11T14:44:01.770Z","updatedAt":"2020-07-17T09:00:02.323Z","presentation":"","name":"La vida chula","ACL":{"gwVBuDTmy9":{"read":true,"write":true},"*":{"read":true},"role:Administrator":{"read":true,"write":true},"role:Master":{"read":true,"write":true}},"__type":"Object","className":"Organization"},"solved":false,"createdAt":"2020-06-17T12:56:19.453Z","updatedAt":"2020-07-18T12:42:27.633Z","days":4,"education":[{"degree":"BEP","domain":null}],"endingAt":{"__type":"Date","iso":"2020-06-30T00:00:00.000Z"},"equipment":[],"income":653.4,"information":"Aucune consigne spécifique pour cette mission, soyez à l'heure et donnez le meilleur de vous-même!","languages":[{"degree":"elementary","field":"en","language":{"className":"Language"}},{"degree":"elementary","field":"es","language":{"className":"Language"}},{"degree":"elementary","field":"da","language":{"className":"Language"}}],"startingAt":{"__type":"Date","iso":"2020-06-25T00:00:00.000Z"},"timeDescription":"Horaires : du lundi au mardi et du jeudi au vendredi de 10:00 à 19:00..","title":"Serveur / Serveuse petit déjeuner","toDo":"Dresser les tables","wage":15,"wagePerHour":null,"wagePerMonth":null,"level":[1,12],"place":{"objectId":"MuohKETlFl","postalCode":"75010","streetName":"Rue des Petites Écuries","streetNumber":"44","town":"Paris","createdAt":"2020-06-17T12:54:48.058Z","updatedAt":"2020-06-17T12:54:48.058Z","ACL":{"*":{"read":true},"gwVBuDTmy9":{"read":true},"role:Administrator":{"read":true,"write":true},"role:Master":{"read":true,"write":true}},"__type":"Object","className":"Place"},"skills":null}]}
The error:
Uncaught (in promise) code: undefined text: "Cannot read property 'name_fr' of null"