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

hasDirtyAttributes: true right after findAll #167

Closed
michDostal opened this issue Apr 9, 2018 · 7 comments
Closed

hasDirtyAttributes: true right after findAll #167

michDostal opened this issue Apr 9, 2018 · 7 comments

Comments

@michDostal
Copy link
Collaborator

Hello I have problem with loading data, right after I load them from backend, entity has hasDirtyAttributes:true and on save its sending complete entity back to backend instead of only changed fields. happens for findAll() and find()

screenshot_7
list.component.ts

ngOnInit() {
this.clients = this.route.snapshot.data['clients'].getModels();
}

client.resolve.ts

export class ClientsResolve implements Resolve<any> {
  constructor(private datastore: ClientDatastore) {
  }

  resolve(route: ActivatedRouteSnapshot): Observable<any> | Promise<any> | any {

    let include = '';
    if (route.data.include) {
      include += route.data.include;
    }
    return this.datastore.findAll(Client, {
      include: include
    });
  }
}

client.routes.ts

{
    path: 'list',
    component: ClientListComponent,
    data: {
      breadcrumb: 'Přehled',
      include: 'advisor'
    },
    resolve: {
      clients: ClientsResolve
    }
  },

client.datastore.ts

const config: DatastoreConfig = {
  baseUrl: environment.apiURL + '/v2',
  models: {
    client: Client,
    advisors: Advisor,
    goals: Goal
  }
};

@Injectable()
@JsonApiDatastoreConfig(config)
export class ClientDatastore extends JsonApiDatastore {
  constructor(http: Http) {
    super(http);
    this.headers = new Headers({'Authorization': 'Bearer ' + localStorage.getItem('token')});
  }
}
@michDostal
Copy link
Collaborator Author

michDostal commented Apr 10, 2018

@abrararshad after some research I found that this problem is caused by this commit(bb1bfdf) where is absolutely ignored if its new instance created from query or not

@Birdr518
Copy link

I can confirm this issue. Using Version 4.1.0 all attributes of my data objects are considered as "dirtyAttributes" - even right after loading them from the backend.


 this.dataStore.findRecord(ApiUsers, "", {}, this.authenticationHeader, 
      ApiStringsService.baseUri + "/my/profile"
    ).subscribe((apiUser: ApiUsers) => {

      console.log(apiUser.hasDirtyAttributes);  // -> true
      apiUser.email = "bla";
      console.log(apiUser.hasDirtyAttributes);` // -> true

});

Using Version 4.0.0 this issue is gone and the first console.log will output false.

But still, if i have an attribute in the form like this:

 @Attribute()
  person:
    {
      title: string,
      firstname: string,
      lastname: string,
      fullname: string,
      gender: number,
      birthday: {
        date: Date,
        timezone_type: number,
        timezone: string
      }
    };

changing one nested attribute like person.title not only person.title isn't considered as a "dirty attribute", nor its parent person (the whole attribute) is stated as "dirty attribute".
Is this behaviour intended?

@michDostal
Copy link
Collaborator Author

@Birdr518 I am currently working on fix and also feature to work better with therse nested attributes. I hope i will be able to create pull request in next week.

@RicardoNeves
Copy link
Contributor

@House-MD any updates on this?

@RicardoNeves
Copy link
Contributor

@House-MD, is there any place where we can see those changes?

@MarkCorneth
Copy link

Currently I fixed it by overriding the entity constructor and manually setting the oldValue and the hasDirtyAttributes property.

constructor(_datastore: JsonApiDatastore, data?: any) {
        super(_datastore, data);
        for (let key in this[AttributeMetadata]) {
            if (this[AttributeMetadata].hasOwnProperty(key)) {
                this[AttributeMetadata][key]['oldValue'] = this[AttributeMetadata][key]['newValue'];
                this[AttributeMetadata][key]['hasDirtyAttributes'] = false;
            }
        }
    }

This way the save function only includes the actually dirty attributes in the PATCH

@House-MD do you have any updates on your fix?

@michDostal
Copy link
Collaborator Author

Hello @RicardoNeves and @MarkCorneth.
I am sorry for my late reply. In branch #167-hasDirtyAttributes is my actual implementation. There is a little bit reworked dirty checking and working with old/newValue.

I also added nested array/object attributes. I am currently testing this solution for nested attributes. I am not happy with it but after maybe 10 different aproaches but this one seems working.

I tried mupltiple solutions with Proxy array/objects but in the end it always had some kind of bug or ended up with infinite loops of getters and apply methods (I still have code to this solution so I will try to finish it but for now this one should be also working. There is one setback -> for nested attributes I had to put their dirtyChecking to method in model -> hasDirtyAttributes which is always called before save and can be triggered by user any time.

michDostal pushed a commit that referenced this issue Sep 11, 2018
…utes

# Conflicts:
#	package-lock.json
#	src/models/json-api.model.ts
michDostal added a commit that referenced this issue Sep 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants