LiveQuery subscribtion on update/leave/enter problem

Only one subscription to Parse.Query("Todo") (Parse-SDK-JS) works correctly.
If two subscriptions are established and the query contains the field with type of date, then this date is set to undefined or string in ISO format: completedAt: "2019-06-18T21:35:53.792Z" or completedAt: undefined.

ps. Websocket message contains:

{ "completedAt":{"__type":"Date","iso":"2019-06-19T21:00:00.000Z" } 

if query not inculde this field (any filters).

And Websocket message contains:

{ "completedAt":"2019-06-19T21:00:00.000Z" }

if query inculde filter like:

{ "completedAt":{"$exists":true,
                 "$lte":{"__type":"Date","iso":"2019-06-19T21:00:00.000Z"} }

Code example

type ACL = any;
interface Pointer<T>{
	type: "Pointer";
	targetClass: T;
}
interface IParseObject {
	ACL: ACL;
	objectId: string;
	createdAt: Date;
	updatedAt: Date;	
}
interface ITodo extends IParseObject  {
	user: Pointer<"_User">;
	name?: string;
	desc?: string;
	completedAt?: Date;
}

let List: ITodo[] = [];


// simplify Parse object
function simplifyObject<T>(parseObject: Parse.Object): T {
	//...
}

// set LiveQuery global autoupdates
async function enableAutoupdate(): Promise<void>{	

	const query = new Parse.Query("Todo");
	query.greaterThan("updatedAt", new Date());
	
	const subscription = await query.subscribe();
	subscription.on("update", (parseObject: Parse.Object)=>{
		//...update a List
		let a = parseObject.get("completedAt");
		console.log(a);
		// undefined !!!
		// but it works if another(fetchCompleted) subscription not set
	});
}

// fetch a list of completed tasks
async function fetchCompleted(): Promise<ITodo[]> {

	const query = new Parse.Query("Todo");
	query.exists("completedAt");

	const subscription = await query.subscribe();
	subscription.on("enter", (parseObject: Parse.Object)=>{
		//...update a List
		let a = parseObject.get("completedAt");
		console.log(a);
		// undefined !!! but it works if another(autoupdate)  subscription not set
	});	
	subscription.on("leave", (parseObject: Parse.Object)=>{
		//...update a List
		let a = parseObject.get("completedAt");
		console.log(a);
		// undefined !!! but it works if another(autoupdate) subscription not set
	});	

	const queryResults:Parse.Object[] = await query.find();
	return queryResults.map(parseObject => simplifyObject<ITodo>(parseObject));
}

function start(): void {	
	enableAutoupdate().then(()=>{
		fetchCompleted().then(list =>{
			List = list;
		}).catch(e=>{});
	}).catch(e=>{})
}

I made quick fix in the code of the server in file parse-server\lib\LiveQuery\QueryTools.js

function matchesKeyConstraints(object, key, constraints) {

  //...
  var _date;
  if (object[key] && object[key].__type == 'Date') {
    _date = object[key];
    object[key] = new Date(object[key].iso);
  } // Equality (or Array contains) cases

  //...
  if (_date) object[key] = _date;
  return true;
}

But I haven’t tested for side effects (

PS. This doesn’t always work: only for original object

@laticq could you please send a PR to Parse Server repository with a test case and your solution?

Ok. I will try, but not today…

1 Like