Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 14:03
    mweststrate closed #2676
  • 14:03
    mweststrate commented #2676
  • 09:17
    lyhistory closed #2715
  • 09:17
    lyhistory commented #2715
  • 09:03
    mweststrate commented #2715
  • 09:00
    urugator commented #2715
  • 08:52
    FredyC unlabeled #2715
  • 08:52
    FredyC labeled #2715
  • 08:52
    FredyC unlabeled #2715
  • 08:52
    FredyC commented #2715
  • 08:51
    FredyC labeled #2715
  • 08:51
    urugator commented #2715
  • 08:51
    FredyC commented #2715
  • 02:53
    lyhistory edited #2715
  • 02:47
    lyhistory edited #2715
  • 02:27
    lyhistory edited #2715
  • 02:23
    lyhistory edited #2715
  • 02:22
    lyhistory edited #2715
  • 02:15
    lyhistory edited #2715
  • 02:10
    lyhistory edited #2715
Bar Ziony
@bartzy
@FredyC really? Did TS deprecate them?
Daniel K.
@FredyC
@bartzy there was never working spec in first place, read the blog post from Michel I linked earlier
Stephen Haney
@StephenHaney
@bartzy In my real projects I'm still using decorators as they're not causing us any build chain pain with nextjs. I find it way better to have the decorator right there with the property/method definition. But we mix observable and non-observable properties on the same object sometimes. If everything is observable, I'd probably just use makeAutoObservable.
Stephen Haney
@StephenHaney
Does anyone know if private class members can be made observable? Either marked with typescript private or es #? Either way, makeObservable's annotation map rejects the property name if it's marked private.
Stephen Haney
@StephenHaney

Ah found my own answer in the docs ā€” you have to tell TS about the private field:

By default TypeScript will not allow you to annotate private fields. This can be overcome by explicitly passing the relevant private fields as generic argument, like this: makeObservable<MyStore, "myPrivateField" | "myPrivateField2">(this, { myPrivateField: observable, myPrivateField2: observable })

Daniel K.
@FredyC
This message was deleted
Stephani Bishop
@stephy
I was wondering if someone can help understand something really quick. I was using makeAutoObservable(this) in my class, and I was getting a warning such as [MobX] Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed. Tried to modify: Connection@389.sessionStarted - then I manually added makeObservable(this, setSessionStarted: action) and the warning is gone. I am wondering why does the auto works for other setters but not for that particular one? Does anyone have more insights or link for documentation about how the makeAutoObservable works? Also, Is it okay to use makeAutoObservable(this) and makeObservable(this, setSessionStarted: action) in the same class?
Stephen Haney
@StephenHaney

@stephy I just ran into a similar problem last night... makeAutoObservable seemed to be missing a class method and not turning it into an action.

One possible gotcha from the docs (this wasn't my case though):

However, makeAutoObservable cannot be used on classes that have super or are subclassed.

Out of curiosity, which syntax are you using to declare your function method? My problem action was using a binding syntax:
myFunc = () => {}

In my case, I switched back to decorators and makeObservable(this), and it's working fine.

One note: I think you can add overrides to makeAutoObservable, so you can probably just put your setSessionStarted: action into the second argument of makeAutoObservable instead of using both makeAutoObservable and makeObservable (I don't know if using both is "bad")

Here's the doc for makeAutoObservable:
https://mobx.js.org/observable-state.html#makeautoobservable
Stephani Bishop
@stephy
@StephenHaney funny I just switched from () => {} to () {} syntax before you sent this message, had a gut feeling that could be it, but switching the syntax didn't do anything. Yes, adding setSessionStarted: action works. I will read more the docs.. thanks for the link!
Stephen Haney
@StephenHaney
Sure, let me know if you figure it out!
scottschafer
@scottschafer

Ah found my own answer in the docs ā€” you have to tell TS about the private field:

By default TypeScript will not allow you to annotate private fields. This can be overcome by explicitly passing the relevant private fields as generic argument, like this: makeObservable<MyStore, "myPrivateField" | "myPrivateField2">(this, { myPrivateField: observable, myPrivateField2: observable })

I just randomly ran across your post this morning and it helped me fix a bug. Thanks!

I wonder if mobx could throw an exception if you tried to write @observable private. This seems like a really bit gotcha.
I'm unclear if @observable protected will work as expected. The docs don't seem to cover that. Trying now.
Stephen Haney
@StephenHaney
Glad it helped :D
scottschafer
@scottschafer
Actually, I'm confused. Here's my code:
  @observable private _isQueueEmpty: boolean = true;
  @observable private _saving: boolean = false;

  @computed get isQueueEmpty() {
    trace();
    return this._isQueueEmpty;
  }

  @computed get saving() {
    trace();
    return this._saving;
  }
Here's my console output:
[mobx.trace] 'OpportunitySavingService@432.isQueueEmpty' is invalidated due to a change in: 'OpportunitySavingService@432._isQueueEmpty'
So it looks like @observable private is working in my code. What gives?
scottschafer
@scottschafer

Incidentally, I'm changing this to:

  @observable readonly isQueueEmpty: boolean = true;
  @observable readonly saving: boolean = false;

And then using the Writeable template to internally modify these fields, like (this as Writeable<SavingService>).saving = true

type Writable<T> = {
  -readonly [K in keyof T]: T[K];
};
Stephen Haney
@StephenHaney
Yeah, after I wrote that, I also ran into some unexpected behavior from private observables. We have a launch on Monday so I just moved on. I'd love to explore it but won't have time until next week.
Hopefully someone will know what's up
scottschafer
@scottschafer
I've become more of a fan of public readonly properties lately. Most of the time when I've declared a property private, it's so I can expose it as a read-only property, so the above pattern makes things simpler.
Bar Ziony
@bartzy
I have an observable value that I want to set some local set (boolean flag) according to changes on it, but also to set it externally in my component on some other change.
I'm trying to avoid using autorun. What am I missing?
the observable: If the user is a pro user. The external event that also changes the boolean flag - some button or whatever. So basically - I have two sources for an observable. How do I do that?
Stephen Haney
@StephenHaney
Hey @bartzy if you put together a minimum reproduction of it in a CodeSandbox or the like, I can take a look
Stephen Haney
@StephenHaney
Here's a fun one: is there a way to use an observable inside a mobx-react-lite observer without wiring up a reaction? Just a one time use of the current value?
Daniel K.
@FredyC
@StephenHaney check discussions on GH, I saw the same question recently there
and generally please try to focus your questions there
Stephen Haney
@StephenHaney
Ah found it, for reference, there's an untracked API you can wrap around your observable usage.
Oh sorry, what's the intended use of this chat?
Daniel K.
@FredyC
well, it's kinda thing of the past before GH introduced discussions
this is unsearchable and messy
Stephen Haney
@StephenHaney
Ah gotcha
Daniel K.
@FredyC
for quick questions it's fine, but not many people are following it here, for anything more elaborate that might be worth keeping around for others, GH is a better choice
Stephen Haney
@StephenHaney
Makes sense, I'll keep that in mind
Alexander Shamshurin
@alex-shamshurin
Hallo guys! Please help, if I use mobx state tree and I have "books" model (map) and some "shelve" which use references to books (types.array(types.references(book)). It's ok. But when I want to clear "shelve" - shelves.clear() it doesn't work ( references are still exists )
Kresimir Cosic
@KresimirCosic
Hello guys, I need some assistance as well. I am trying to save stores' data to localStorage everytime the data changes. The autorun function is not really running automatically when I do something to the array of models in my case for example:
constructor(rootStore: RootStore) {
    makeObservable(this, {
      makes: observable,
      models: observable,
      addMake: action,
      editMake: action,
      removeAllModelsOfMake: action,
      removeMake: action,
      addModel: action,
      editModel: action,
      removeModel: action,
    });
    this.rootStore = rootStore;
    autorun(() => {
      console.log('Models store changed', this.models);
    });
  }
When I delete a model, change it, create a new one, it doesn't run the function in autorun. What am I doing wrong?
autorun works on an example where data is either some kind of an object (i.e. User with different fields) or it's undefined, I guess then it sees a difference between undefined and a User type object.
Kresimir Cosic
@KresimirCosic
Running this instead is actually triggering the autorun every time: autorun(() => { console.log(this.models.filter((model) => model.price >= 20000)); });
Kresimir Cosic
@KresimirCosic
Considering I need to find all the models and makes in my store (to save them to localStorage, I can get the data via the Array.prototype.filter in the autorun method? Do you think that's a bad approach?
Stephen Haney
@StephenHaney
Hey @KresimirCosic in your original example, you are only observing the models object, which I'm guessing does not actually change when you make changes to your data. That is, even if you change properties of models, the models object itself is the same object, equal to itself, and will not trigger a rerun of that function.
In an autorun, you need to use the actual properties that will change, as you are when you filter and observe model.price
In this type of situation I reach for deepObserve from the mobx-utils package, but you could certainly use autorun too
If my goal was to store the full tree as stringified json, I'd probably do something like:
autorun(() => saveMyStuff(JSON.stringify(this.models));

// note that this observes every property all the way down the tree of models
// since JSON.stringify will deeply loop through every property
If your data is large or you do this often, you will need to keep aware of the time complexity (and then maybe look towards only updating the data that's changed with deepObserve)
Kresimir Cosic
@KresimirCosic
Hey @StephenHaney thank you for your input. I will definitely try your approach, and check the deepObserve as well. Thank you for your information, I will get back to you with my results; after the holidays probably :P. Cheers!
dLLama
@mvoloz_twitter
:wave:
hoping someone can point me in the right direction, new to mobx, historically have used mostly redux/redux-saga, redux-observables and graphql, iā€™m having a bit of trouble understanding how to connect to a websocket, more importantly, observing the readystate on teh socket it self.