Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assignation of @observable property not working after 2.1.3+1 ! #933

Closed
ed-oo opened this issue Sep 13, 2023 · 3 comments
Closed

Assignation of @observable property not working after 2.1.3+1 ! #933

ed-oo opened this issue Sep 13, 2023 · 3 comments
Assignees
Labels
question Further information is requested

Comments

@ed-oo
Copy link

ed-oo commented Sep 13, 2023

Hello,

The assignation of @observable property not working if property != null;


  @observable
  Ticket? ticket;

  @action
  updateTicket(Message message) {
        // Here this.ticket != null because it's set before
        // Here this.ticket.id == message.data.id
        // Here this.ticket.updatedAt != message.data.updatedAt
        this.ticket = message.data;
        // Here this.ticket.updatedAt is always != message.data.updatedAt
        // What is this witchcraft ?
  }

Important note Ticket have a custom equals and hash code based uniquely on ticket.id property.

Is this the desired behaviour ?

@scipio3000
Copy link

Hello,
I'm encountering a similar problem. When I try to re-assign an observable property, it doesn't update properly.
I also have a custom equals/hashcode set-up on an identifier.
It was fine in 2.1.3

@amondnet amondnet added the question Further information is requested label Sep 15, 2023
@amondnet amondnet self-assigned this Sep 15, 2023
@amondnet
Copy link
Collaborator

amondnet commented Sep 15, 2023

https://github.com/mobxjs/mobx.dart/blob/master/mobx/CHANGELOG.md#214
@scipio3000 @ed-oo

Yes Prior to 2.1.4, this caused an unnecessary reaction even when the value hadn't actually changed. This was unintended behaviour. From 2.1.4, as intended, reactions are only fired if the value has actually changed, which reduces unnecessary builds and improves performance.

#855

@readonly
int _value;

void setValue(int value) {
  _value = value;
}

2.1.3

setValue(1); // reaction
setValue(1); // reaction

2.1.4

setValue(1); // reaction
setValue(1); // No reaction occurs

#907
https://github.com/mobxjs/mobx.dart/blob/master/mobx/CHANGELOG.md#220

If you don't care about unnecessary builds and performance, use @alwaysNotify ( works same as previous @observable).

  @alwaysNotify
  Ticket? ticket;

  @action
  updateTicket(Message message) {
        // Here this.ticket != null because it's set before
        // Here this.ticket.id == message.data.id
        // Here this.ticket.updatedAt != message.data.updatedAt
        this.ticket = message.data;
        // Here this.ticket.updatedAt is always != message.data.updatedAt
        // What is this witchcraft ?
  }

However, the recommended approach is

  1. Ticket to implement operator ==, so that mobx can verify that the value has actually changed.

    class Ticket {
      @override
      bool operator ==(Object other) =>
          identical(this, other) ||
          other is Ticket &&
              runtimeType == other.runtimeType &&
              id == other.id &&
             updatedAt == other.updatedAt;
    }
  2. to use custom equals when creating observables https://pub.dev/documentation/mobx/latest/mobx/MakeObservable-class.html

    bool customEquals(Ticket? oldValue, Ticket? newValue) => // implement ;
    @MakeObservable(equals: customEquals)
    Ticket? ticket;
  3. or make Ticket a store. https://mobx.js.org/defining-data-stores.html#example-domain-store

@ed-oo
Copy link
Author

ed-oo commented Sep 15, 2023

Thank you for your time, I understand better now ! :)

@ed-oo ed-oo closed this as completed Sep 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants