Parse-SDK-JS icon indicating copy to clipboard operation
Parse-SDK-JS copied to clipboard

Possible inconsistency with include

Open bawahakim opened this issue 4 years ago • 7 comments

Issue Description

It seems when we query and get and object, it automatically includes all nested fields. This makes it inconsistent to know if we are getting an Object or a Pointer

Steps to reproduce

  1. Create a new Parse Object which has a pointer field to another class, called pointer.
  2. Query the object with get. Don't use the include method
  3. Check the type of pointer

Actual Outcome

pointer is an Object

Expected Outcome

pointer should be a Pointer

Environment

react 17.0.1 next 10.0.1

Server

  • Parse Server version: 4.3.0
  • Operating system: Macos / Linux
  • Local or remote host (AWS, Azure, Google Cloud, Heroku, Digital Ocean, etc): Local and Heroku

Database

  • System (MongoDB or Postgres): Postgres
  • Database version: 12
  • Local or remote host (MongoDB Atlas, mLab, AWS, Azure, Google Cloud, etc): Heroku

Client

  • Parse JS SDK version: 2.18.0

Logs

bawahakim avatar Jan 13 '21 18:01 bawahakim

Are you referring to typeof pointer or __type = Pointer?

dplewis avatar Jan 13 '21 18:01 dplewis

Are you referring to typeof pointer or __type = Pointer?

typeof pointer. It returns a ParseObject, not a ParsePointer, and I can access all the methods and attributes of the object.

bawahakim avatar Jan 15 '21 15:01 bawahakim

Can you write a test case to reproduce this? I’ve seen other users post this or a similar issue but we never have enough information to reproduce it.

dplewis avatar Jan 15 '21 15:01 dplewis

@bawahakim What does object.toJSON() return for you? I don't see a reference to ParsePointer anywhere in the SDK.

dplewis avatar Feb 11 '21 04:02 dplewis

Hey @dplewis

I've dugged a bit more into this. I've been pretty busy these last weeks and couldn't get back, sorry about that.

So in this first image, I've queried a class called Program that contains a Pointer to another class called Category.

image

The first time we fetch the Program without including Category we get what is expected : a pointer without the attributes. Weirdly enough, the toJSON() gives us a pointer, but the one without toJSON()` (second picture) gives us an object. image image

Now here comes the weirdest part. After fetching again with include, the original object that did not include the Category, now has the full object data.

image

Then something clicked, I remember reading on Stack Overflow that Parse treats two Parse Objects with the same object Id as one object, even if you do a deep clone with Lodash . So I did a bit more tests and this seems to be reproduceable. Example of a Game object that has a profile attribute, that is a pointer to a Profile class that has name attribute.

const game = await new Parse.Query("Game").first();
const profile = game.attributes.profile
console.log(profile.toJSON()) // here you will only get an `objectId`
const sameGameWithProfile = await new Parse.Query("Game").include('profile').first()
console.log(profile.toJson()) // here you will get the full profile including the name

The issue here is that we are mutating an object without really knowing it. This is also the case if we are fetching another another class or object that happens to include the Profile ; it will mutate your original object without you knowing. To make 100% sure, I used the disableSingleInstance() static method, and indeed, now I get the expected response.

image

bawahakim avatar Feb 14 '21 03:02 bawahakim

I’ve personally seen this happen but it was 3 years ago. This is really helpful and you say it’s reproduceable? SingleInstance might be the issue here.

Can you create a separate project. (No server key) or a test case that fails?

dplewis avatar Feb 14 '21 03:02 dplewis

I can create a separate project, but that will have to wait a bit as I don't have much free time at the moment.

bawahakim avatar Feb 14 '21 04:02 bawahakim