Hi there !
It there any way to subscribe to attribute changes of an Parse.Object ?
I use react and It would be awesome if we could rerender a component when an object attribute change,
so the UI stays in sync with the cache
I wanted to override a mutating function so I can add a callback, but It seems that there is multiple functions affecting the state of the object attributes ( to handle the data from server and the optimistic data )
Also, it seems to me that there is no way to relate the object attributes to the ParseObject itself, so even if we abstract the mutating part of all the setServerData, mergeFirstPendingState, ... mutating functions into it own applyNewData function, we cannot access the ParseObject to let it know the state is changed
Anyone has any thoughts on this ? :)
Thanks !
I've struggled a lot with this (using Vue). I had to build my own solution using Object.defineProperty (ES6-Proxy doesn't have proper IE support) which essentially proxies all the attributes.
It's a bit complicated, but look into ParseObject.dirtyKeys - it gives you the keys that were changed.
I think this needs a major rewrite of some parts in the SDK to support React, Vue and others out of the box (using POJOs and events or hooks).
Historically, Parse used the Backbone.Model, that's the reason it's not very compatible with the current generation of web frameworks. Changing the interface would be a major thing that I don't think will happen for compatibility reasons.
I Actually succeded using events and HOC's, and overloading the save / destroy / set methods of Parse.Object
If anyone needs help on this, ask here
Maybe In the future I will write a react-parse package, in the Apollo style
Have you had a look at this project? https://github.com/andrewimm/parse-lite
On Jul. 7, 2018, 12:13 +0200, Elies Lou notifications@github.com, wrote:
I Actually succeded using events and HOC's, and overloading the save / destroy / set methods of Parse.Object
If anyone needs help on this, ask here
Maybe In the future I will write a react-parse package, in the Apollo style
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
It looks nice but I was really looking for advanced cache management ( I actually used the LiveQueryTools file from server to update cached queries on client when a subscription event or rest save occurs )
@Aetherall Would love to see your code.
@samuelantonioli
You have to create a class extending Parse.Object and add to it subscription abilities
export default class Collection extends Parse.Object {
// === === === React Compat === === ===
// === Override mutators ===
async save(...args) {
const res = await super.save(...args)
this.dispatch()
return res
}
async destroy(...args) {
const res = await super.destroy(...args)
this.dispatch()
return res
}
set(...args) {
super.set(...args)
this.dispatch()
return this
}
// ..... others mutation methods
// === Events ===
get hook() {
const id = this._getId()
if (this.__id !== id) {
if (this.__id) this.changeHook() //throw new Error('THE ID CHANGED', this)
this.__id = id
}
return this.__id
}
changeHook(newId) {
const oldId = this.__id
const actualListeners = EventManager.listeners(oldId)
EventManager.off(oldId)
for (const listener of actualListeners) EventManager.on(newId, listener)
this.__id = newId
}
dispatch = () => {
EventManager.emit(this.hook)
this.__parent && this.__parent.dispatch()
}
subscribe = cb => {
EventManager.on(this.hook, cb)
return () => {
EventManager.off(this.hook, cb)
}
}
unsubscribe = cb => {
EventManager.off(this.hook, cb)
}
}
and create an hoc to subscribe to an Item:
export default function reactive(itemProp = 'item') {
return Comp =>
class Reactive extends Component {
u = () => this.forceUpdate()
updateListener = () => {
const item = this.props[itemProp]
if (item !== this.cacheItem) {
this.cacheItem && this.cacheItem.unsubscribe(this.u)
item && item.subscribe(this.u)
this.cacheItem = item
}
}
componentDidMount() {
this.updateListener()
}
componentWillUnmount() {
this.props[itemProp] && this.props[itemProp].unsubscribe(this.u)
}
render() {
this.updateListener()
return <Comp {...this.props} />
}
}
}
@Aetherall this is a very neat solution and adds nice features to a Parse.Object. Any chance you can make it through prototype injection? This way using Parse.Object with your trick will play nice with event driven paradigms.
It was my plan at the beginning, but I was not done adding stuff to the Parse.Object class, so first, I created this "class in the middle"
I added abilities like this:
<somepost.fields.title/>
<somepost.fields.avatar aspectRactio={1} />
I added field level validation and authorization, the ability to save many deeply nested unsaved children in the same request, MongoDB multi-document transactions, self-maintaining queries... and many other things I can't find a framework for
Very interesting, you’re building your own framework in the end.
Yeap, I am looking for the perfect framework for 3 years now, I've been through a lot of techs, and the way parse see the data is really cool
Very interesting, in any cases, I’ve been wondering how to split parse server better (data, identity, push etc...) both logically (node modules) and from an http endpoint perspective. Perhaps rhat’s Something you’d need in your project, leveraging the data core without the rest.
That's exactly what I am working on
I would be happy to hear your suggestions
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Closing via https://github.com/parse-community/Parse-SDK-JS/pull/731#issuecomment-462196616
Most helpful comment
@samuelantonioli
You have to create a class extending Parse.Object and add to it subscription abilities
and create an hoc to subscribe to an Item: