Code Monkey home page Code Monkey logo

ember-data-change-tracker's People

Contributors

artemgurzhii avatar averydev avatar danielspaniel avatar davelindquist-egistix avatar denzo avatar dependabot[bot] avatar ember-tomster avatar ezekg avatar furkanayhan avatar heroiceric avatar inad avatar janmisek avatar knownasilya avatar migbar avatar ming-codes avatar richardfrosztega avatar runspired avatar san650 avatar sergeastapov avatar subtletree avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ember-data-change-tracker's Issues

belongsTo tracking not working Ember Data 3.3.2

When i change belongsoTo modelChanges == {}
/test-model

export default DS.Model.extend({
  changeTracker: { only: ['belongs', 'name', 'manyMany'] },
  name: DS.attr('string),
  belong: DS.belongsTo('belong'),
  manyMany: DS.hasMany('many-many')
});

testModel.startTrack();
if i set hasMany
testModel.set('manyMany', [this correct data])
modelChanges {manyMany: true} it ok

testModel.set('belong', this correct data )
modelChanges {}

Install fails with ember-cli 2.15.1 and yarn

ember install ember-data-change-tracker
Command failed: yarn add --dev ember-data-change-tracker --non-interactive
warning [email protected]: The engine "ember-cli-app-version" appears to be invalid.
error [email protected]: The engine "node" is incompatible with this module. Expected version "^4.5 || 6.* || 7.*".
error Found incompatible module

yarn add v0.27.5
[1/4] Resolving packages...
[2/4] Fetching packages...
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

Error: Command failed: yarn add --dev ember-data-change-tracker --non-interactive
warning [email protected]: The engine "ember-cli-app-version" appears to be invalid.
error [email protected]: The engine "node" is incompatible with this module. Expected version "^4.5 || 6.* || 7.*".
error Found incompatible module

yarn add v0.27.5
[1/4] Resolving packages...
[2/4] Fetching packages...
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

    at Promise.all.then.arr (/Users/bhunt/Nvidia/Code/NVProjectPlanUI/node_modules/execa/index.js:231:11)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:169:7)

Is this add-on still working?

I'm struggling to get any of the isDirty or hasDirtyRelationships to work. I've followed the installation instructions but I don't see any additional model capabilities.

Object type not tracked properly on creating new record

I have an object type attribute in my model. I am creating a new record and the data is saved to the back. Now when I try to edit the data, change any of the keys in the object type and discard the changes. But the values of the object type is not rolled back properly. This occurs only when I create a new record. But not when I reload the entire page and get the data from the backend. Below is my model.

model.js

export default DS.Model.extend(Validations, {
  start_year: DS.attr('string'),
  end_year: DS.attr('string'),
  created_at: DS.attr('datetime'),
  academic_degree: DS.attr('', {defaultValue() {return {};}}),
});

Unchanged hasMany causing isDirty

I'm working on some code to autosave my model. It looks like:

export default Route.extend({
  autosave: task(function * () {
    yield timeout(3000);
    this.get('model').save();
  }).restartable(),

  model(params) {
    return this.store.findRecord('task', params.taskId);
  },

  afterModel(model) {
    this.set('model', model);
  },

  modelChanged: observer('model.isDirty', function() {
    if(this.get('model.isDirty')) {
      window.console.log(this.get('model').changed());
      this.get('autosave').perform();
    }
  })
});

I have the model configured with: changeTracker: { trackHasMany: true, auto: true, enableIsDirty: true }

When I change a string "deliverables" attribute in the model, I get on the console:

{deliverables: Array(2), subscribers: true}
{subscribers: true}
{}

Why does it think subscribers changed? subscribers is modeled as: subscribers: hasMany('user', {inverse: null})

Attributes set at create-time are always changed

Consider the model:

import Model from 'ember-data/model';
import attr from 'ember-data/attr';

export default Model.extend({
  country: attr('string'), // e.g. US
  region: attr('string'), // e.g. Illinois
  locality: attr('string'), // e.g. Chicago
  street: attr('string'), // e.g. 1060 W Addison St
  postalCode: attr('string') // e.g. 60613
});

What I'm finding is that any attributes that are set at create-time are always changed, even if auto is set to false, e.g.:

let address = store.createRecord('address', { country: 'AR' });
address.didChange('country'); // => true

I would expect the tracker to start after the record is created when auto is true. Even more frustrating, I can't set auto to false and call address.startTrack() after createRecord() to do it manually.

except not filtering change

I updated my model to include an except on the "updatedOn" field so I could set it when the model is saved. Now, when I save the model, I get into an infinite loop with updatedOn flagged as changed.

Here is the model config: changeTracker: { trackHasMany: true, auto: true, enableIsDirty: true, except: ['updatedOn'] }

Here is the save code:

export default Route.extend({
  autosave: task(function * () {
    yield timeout(3000);
    this.set('model.updatedOn', moment());
    this.get('model').save();
  }).restartable(),

  model(params) {
    return this.store.findRecord('task', params.taskId);
  },

  afterModel(model) {
    this.set('model', model);
  },

  modelChanged: observer('model.isDirty', function() {
    if(this.get('model.isDirty')) {
      window.console.log(this.get('model').changed());
      this.get('autosave').perform();
    }
  })
});

And the output from the console:

{deliverables: Array(2), subscribers: true}
{deliverables: Array(2), updatedOn: Array(2), subscribers: true}
{subscribers: true}
{updatedOn: Array(2)}
{}
{updatedOn: Array(2)}
{updatedOn: Array(2)}

rollback of pristine model with hasMany causes removal of hasMany elements

Hi, thanks for the useful addon!

I've been using the rollback feature on a model that has a hasMany collection of another model but when rolling this parent model back, even when its in a pristine condition, i.e., the parent model has no changes and the child hasMany models all have no changes and the hasMany relationship itself was not modified (as in no models were added or deleted from the collection), it causes its hasMany collection to be emptied! The collection of hasMany models remain in the store though. The model was not sideloaded with its hasMany though, so I wonder if this is a known limitation or whether it's a bug or just the way it's supposed to be?

Not sure if this is related to issue #4

Thanks,

Issue with `rollback` not rolling back `hasMany`

I'm trying to make use of the rollback function and it's not working in my case. I have auto-tracking set to true, and I have a hasMany relationship that contains a belongsTo relationship. I'm using Ember and ember-data @ 2.11.

When I call rollback, it uses the ids of the hasMany relationship (configs):

screen shot 2017-02-14 at 12 03 39 pm
However, by the time it gets to the serializer's normalize function, relationships is empty, and the rollback is ineffective:

screen shot 2017-02-14 at 12 04 14 pm

(Note: type is also undefined, which I was easily able to avoid by extending the normalize function by adding the type after the fact)

Am I misunderstanding how this addon should be used, or is there a genuine issue here? Thank you!

Nested dirtyness

I didn't see any example of keeping track of nested levels of "dirtyness", so I assume this feature either isn't implemented or the user is supposed to use another approach for it.

Example: If I update a project's name, and projects is a hasMany relationship on user, I'd like user.get('isDirty') to return true.

Is this possible? How would you recommend tackling this problem?

The immediate solution that comes to mind would be

// models/user.js
// ...
isDeepDirty: computed('[email protected]', function() {
  return this.get('projects').any((p) => p.get('isDirty'));
})

And you would probably need to call startTrack() on all projects?
This also creates a separate computed property. Just wondering if anyone has an alternative approach they could share.

new models with default values cannot be tracked properly

As far as I see; new models always return true for didChange attr/relation after the following commit fe3a1a3#diff-d1f63f06d3656a6e2da38e3a5fee9865R406

I need to start tracking of a newly created model after setting some default attributes on it; but calling model.startTrack() (I am not using auto mode) has no effect due to the above commit I mentioned. I cannot find anyways to start tracking of a new model after setting some initial values on it; so that modelChanges() do not return the properties with those initial values if they are unchanged. Is there anyway I can achieve what I want? I am open to any suggestion. thx.

hasDirtyRelations not working on multiple belongsTo

I have a model with two belongsTo attribute. When a change the first belongsTo relation, hasDirtyRelations is triggered perfectly but on changing the second one, I get false for hasDirtyRelations.

qualification.js

export default DS.Model.extend(Validations, {
  profile: DS.belongsTo('profile'),
  degree: DS.belongsTo('degree')
});

profile.js

export default DS.Model.extend({
  name: DS.attr('string'),
  country: DS.attr('string'),
  qualifications: DS.hasMany('qualification')
});

degree.js

export default DS.Model.extend({
  name: DS.attr('string'),
  type: DS.attr('string'),
  country: DS.attr('string')
});

Serializer

export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
  attrs: {
   profile: { embedded: 'always' },
   degree: { embedded: 'always' }
  }
});

The relationships are established perfectly in both the cases for profile and degree and I could able to retrieve values from both the models. But if any value gets changed in degree model, qualification.get('hasDirtyRelations') returns false while the same returns true if there is any change in profile data. Is there anything that am missing out? The configs are enabled in the environment

Pushing a belongsTo change causes record to be dirty.

If I have a record which is not dirty, and now push an update to the store that contains a belongsTo update (for that record), the record will be dirty after the push.

test('when model.belongsTo is pushed to store, do not dirty', function(assert) {
  let company1  = make('company');
  let company2  = make('company');

  let userJson = build('user', {id: '1111',name: 'bob',company: company1});

  let normalized = Tracker.normalize(make('user'), userJson.get());

  let user = run(() => FactoryGuy.store.push(normalized));
  assert.deepEqual(user.get('name'), 'bob', 'newly pushed user has correct info');
  assert.deepEqual(user.savedTrackerValue('company'), {id: company1.id, type: 'company'}, 'newly pushed user has correct company');
  assert.notOk(user.get('isDirty'), 'newly pushed user is not dirty');

  userJson = build('user', {id: '1111', company: company2});
  normalized = Tracker.normalize(make('user'), userJson.get());
  delete normalized.data.attributes.name;
  let user3 = run(() => FactoryGuy.store.push(normalized));
  assert.equal(user, user3, 'pushed update is the same user');
  assert.deepEqual(user3.get('name'), 'bob', 'pushed updated user has correct info');
  assert.deepEqual(user.savedTrackerValue('company'), {id: company2.id, type: 'company'}, 'tracker has correct company');
  assert.deepEqual(user3.belongsTo('company').id(), "2", 'pushed updated user has correct company');
  assert.notOk(user3.get('isDirty'), 'pushed update user is not dirty');
});

saveChanges doesn't flush changed attributes

After using appointment.saveChanges(), I still see attributes in appointments.changed(), coming from appointment.changedAttributes().

Calling appointment._internalModel.flushChangedAttributes() would solve the problem.

Ember 3.14

Hello,

I am getting this error on 3.14 (with ember-data 3.13 and 3.14):

Error: Assertion Failed: You attempted to update [object Object].hasAnyRelationshipData to "true", but it is being tracked by a tracking context, such as a template, computed property, or observer. In order to make sure the context updates properly, you must invalidate the property when updating it. You can mark the property as `@tracked`, or use `@ember/object#set` to do this.
    at assert (index.js:172)
    at ManyRelationship.set [as hasAnyRelationshipData] (index.js:790)
    at ManyRelationship.setHasAnyRelationshipData (-private.js:10663)
    at ManyRelationship.updateRecordDatasFromAdapter (-private.js:10652)
    at ManyRelationship.updateData (-private.js:10999)
    at ManyRelationship.push (-private.js:10704)
    at RecordDataDefault._setupRelationships (-private.js:11532)
    at RecordDataDefault.didCommit (-private.js:11629)
    at InternalModel.adapterDidCommit (-private.js:5961)
    at Store.didSaveRecord (-private.js:14140)

Not tracking the changes on the model fixes it, so it is related to the tracking itself. This happens after a successful save as you can see, when the data is reloaded.

Ember inspector fails to inspect model when enableIsDirty is set

config:
changeTracker: { trackHasMany: true, auto: true, enableIsDirty: true }

attempting to inspect a model renders:

You can report bugs at https://github.com/emberjs/ember-inspector.
Error message: Assertion Failed: You attempted to access `hasDirtyAttributes.type` (on `<safechain-ops-ui@model:order::ember635:gy1m2Zv>`), but `hasDirtyAttributes` is a computed property.

Due to certain internal implementation details of Ember, the `hasDirtyAttributes` property previously contained a private "descriptor" object, therefore `hasDirtyAttributes.type` would have been `undefined`.

This implementation detail has now changed and the "descriptor" object is no longer present at this location. Soon, accessing `hasDirtyAttributes` on this object will return the computed property's current value (see RFC #281 for more details).

If you are seeing this error, you are likely using an addon that relies on this now-defunct private implementation detail. If you can, identify the addon from the stack trace below and report this bug to the addon authors. If you feel stuck, the Ember Community Slack (https://ember-community-slackin.herokuapp.com/) may be able to offer some help.

If you are an addon author and need help transitioning your code, please get in touch in the #dev-ember channel in the Ember Community Slack.
Stack trace: Error: Assertion Failed: You attempted to access `hasDirtyAttributes.type` (on `<safechain-ops-ui@model:order::ember635:gy1m2Zv>`), but `hasDirtyAttributes` is a computed property.

Due to certain internal implementation details of Ember, the `hasDirtyAttributes` property previously contained a private "descriptor" object, therefore `hasDirtyAttributes.type` would have been `undefined`.

This implementation detail has now changed and the "descriptor" object is no longer present at this location. Soon, accessing `hasDirtyAttributes` on this object will return the computed property's current value (see RFC #281 for more details).

If you are seeing this error, you are likely using an addon that relies on this now-defunct private implementation detail. If you can, identify the addon from the stack trace below and report this bug to the addon authors. If you feel stuck, the Ember Community Slack (https://ember-community-slackin.herokuapp.com/) may be able to offer some help.

If you are an addon author and need help transitioning your code, please get in touch in the #dev-ember channel in the Ember Community Slack.
    at new EmberError (http://localhost:4200/assets/vendor.js:28634:25)
    at Object.assert (http://localhost:4200/assets/vendor.js:28877:15)
    at Object.get (http://localhost:4200/assets/vendor.js:38317:42)
    at addProperties (<anonymous>:3145:40)
    at mixin.mixins.forEach.mixin (<anonymous>:3116:11)
    at Array.forEach (<anonymous>)
    at propertiesForMixin (<anonymous>:3114:20)
    at Class.mixinsForObject (<anonymous>:3004:22)
    at Class.sendObject (<anonymous>:2923:26)
    at Class.inspectModel (<anonymous>:740:37)

links object in POST response dirtying relationship

Say I do a POST to create a photo with a photographer relationship,

POST /photos HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "photos",
    "attributes": {
      "title": "Ember Hamster",
      "src": "http://example.com/images/productivity.png"
    },
    "relationships": {
      "photographer": {
        "data": { "type": "people", "id": "9" }
      }
    }
  }
}

The following JSON API compliant response to the POST makes the photographer relationship dirty (owing to the links object in the response),

{
  "data": {
    "id": 1,
    "type": "photos",
    "attributes": {
      "title": "Ember Hamster",
      "src": "http://example.com/images/productivity.png"
    },
    "relationships": {
      "photographer": {
        "links": {
           "self": "/api/photos/1/relationships/photographer",
           "related": "/api/photos/1/photographer" 
         },
        "data": { "type": "people", "id": "9" }
      }
    }
  }
} 

This means that a subsequent PATCH operation on this record (triggered by an update to title for example) will pass the photographer relationship in the request, despite the client not modifying it. Is there a way this can be avoided?

Don't rollback deleted relationships

During testing I figured out that rollback() also brings back related resources that might've been already deleted and saved (state root.deleted.saved). IMO these have to be excluded from the rollback otherwise you'd end up with a pretty error-prone state.

I can also have a look at how to do this. Anyways I guess it's kind of an edge case. Nevertheless it's something we have to think about. I can provide a user-case if there are more questions.

Belongs to relationship is always null even though ID is present

Using the keepOnlyChanged serializer mixin, with auto tracking enabled.

var ENV = {
  // โ€ฆ
  changeTracker: { trackHasMany: true, auto: true },
  // โ€ฆ
}
import DS from 'ember-data'

export default DS.Model.extend({
  product: DS.belongsTo('product')
})

When logging the tracker initialization, it looks like the serialization for every belongs to relationship returns null, because model.belongsTo(rel).value() returns null. I can work around this by updating the belongs to serializer utility to use model.belongsTo(rel).id(), which oddly returns the correct ID, but doesn't account for polymorphic relationships:

// ember-data-change-tracker/addon/utilities.js

export const relationShipTransform = {
  belongsTo: {
    serialize(model, key, options) {
      let value = model.belongsTo(key).id();
      return value;
    },

    deserialize() {
    }
  },
  // โ€ฆ
}

I have a few polymorphic relationships, so in the end, this isn't going to work. The real question I can't figure out is why value() returns null, yet id() returns the correct ID. Is it maybe because the relationship is not fully loaded?

Belongs to relationship data is returned like this via the JSON API, including with linkage (type+id) as well as a related link:

"relationships": {
  "product": {
    "links": {
      "related": "/v1/users/0b4b1a9a-e25a-4f14-a95e-d9dd378d6065/product"
    },
    "data": {
      "type": "products",
      "id": "3ab38aae-bbf7-4846-9c32-af9d94bf5ad4"
    }
  }
}

Ember and Ember data are up to date. Using latest version of this package as well.

Any ideas?

array gets "rolled back" to string

It wasn't quite clear to me from the README whether rolling back an array property should work (give me the original array back) or not (leaving the change in the array), so I tried it out. The result was ... unexpected: a string representation of the original array.

$E.get('arrayProp')
[]
$E.get('arrayProp').push('something')
1
$E.get('arrayProp')
["something"]
$E.changed()
Object {arrayProp: true}
$E.rollback()
undefined
$E.get('arrayProp')
"[]"

This addon will break when used together with ember-cli-mirage

It took us a while to figure out what the problem is but in our application we use both ember-data-change-tracker and ember-cli-mirage. After upgrade from 0.7.7 to 0.8.0 we noticed that if Mirage is enabled, methods like startTrack() are missing on all models.

I found a fix, it's about adding before: 'ember-cli-mirage' to https://github.com/danielspaniel/ember-data-change-tracker/blob/master/app/initializers/ember-data-change-tracker.js

But the problem is it will fail in case ember-cli-mirage is not present in the project. I was also trying to debug ember-cli-mirage but I wasn't able to find any place which I could fix to make this addon work.

Maybe authors of this addon would have some idea how to fix it. I'm not that familiar with the internals of Ember.js. The help would be very appreciated. Thank you

change isDirty by removing from hasMany

Thanks a lot for this project!
I know that removing/adding from hasMany relationships seems to reflect on the .changed() result, but does the same happen with the isDirty property?

user.get('projects').removeObject(firstProject); // remove project1
user.changed() //=> {projects: true }
user.get('isDirty') //=> this returns false, but it should return true

I wonder if I'm doing some configuration wrong or if this isn't supposed to work.

Additional info:
using addObject on a hasMany seems to set isDirty to true.

computed property for hasDirtyRelationships?

i'm in need of a computed property like hasDirtyRelationships that i can compose with hasDirtyAttributes. the simple use case is binding the disabled property of a save button on a form in a template that is disabled until the underlying model has been modified.

thanks for the work, this is a much needed addition to models.

isDirty can't be used as a computed property key

Here's a reproduction
master...alexander-alvarez:computed-property-bug
The computed property should be dirty too (permutation one) test case failes
The computed property should be dirty too (permutation two) test case passes

May have to do with the fact we dont notifyPropertyChange('isDirty'), but there could be something else since we defined properties on the fly like https://github.com/danielspaniel/ember-data-change-tracker/blob/master/addon/tracker.js#L462...L479

Either way wanted to bring it up and start a discussion

Merge into Ember Data

Has there been any discussions with the Ember Data team about moving this functionality into Ember Data?

Basically, to use this addon as the starting point for an RFC that builds on emberjs/rfcs#21, but probably supersedes it in a few ways.

It would be very useful! ๐ŸŽˆ

belongsTo relationships set in createRecord aren't tracked properly

v0.5.6. changeTracker.auto is set to true in the global configuration. order belongsTo project (async); project hasMany order (async).

let project = store.createRecord('project');
let order = store.createRecord('order', { project });

console.log(order.savedTrackerValue('project')); // => null

Calling saveChanges() and/or startTrack() on order has no effect on the outcome.

Extending to support buffered mode?

Would you be open to having a buffered mode? / how hard would it be to leverage the same tracking mechanism you have but in addition to:

    let info = {foo: 1};
    let projects = makeList('project', 2);
    let [project1] = projects;
    let pets = makeList('cat', 4);
    let [cat, cat2] = pets;
    let bigCompany = make('big-company');
    let smallCompany = make('small-company');

    let user = make('user', { profile: profile1, company: bigCompany, pets, projects });

   // manual tracking model means you have to explicitly call => startTrack
    // to save the current state of things before you edit
    user.startTrack();   

    // edit things  
    user.setProperties({
      'info.foo': 3,
      company: smallCompany,
      profile: profile2,
      projects: [project1],
      pets: [cat1, cat2]
    });

    user.rollback();

    // it's all back to the way it was
    user.get('info') //=> {foo: 1}
    user.get('profile') //=> profile1
    user.get('company') //=> bigCompany
    user.get('projects') //=> first 2 projects
    user.get('pets') //=> back to the same 4 pets

we could also do:

   // manual tracking model means you have to explicitly call => startTrack
    // to save the current state of things before you edit
    user.startTrack({buffered: true});   

    // edit things  
    user.setProperties({
      'info.foo': 3,
      company: smallCompany,
      profile: profile2,
      projects: [project1],
      pets: [cat1, cat2]
    });

    // nothing has changed
    user.get('info') //=> {foo: 1}
    user.get('profile') //=> profile1
    user.get('company') //=> bigCompany
    user.get('projects') //=> first 2 projects
    user.get('pets') //=> back to the same 4 pets

    user.applyChanges();

     // changes are applied
    user.get('info') //=> {foo: 3}
    user.get('profile') //=> smallCompany
    user.get('company') //=> profile2
    user.get('projects') //=> [project 1]
    user.get('pets') //=>  [cat1, cat2]

a la
https://github.com/yapplabs/ember-buffered-proxy

hasDirtyRelations seems not work any more

This is my first time to use this addon, so I don't know what's the status previously, but seems hasDirtyRelations CP not working.

this is the test:

image

this are the definitions for both model:

// car-model
export default DS.Model.extend({
  name: attr('string'),
  description: attr('string'),
  disabled: attr('boolean'),

  'car-type': belongsTo('car-type'),
})

// car-type
export default DS.Model.extend({
  name: attr('string'),
  description: attr('string'),

  'car-models': hasMany('car-model'),
})

and I turned of `enableIsDirty` if `config/environment.js`:

```javascript
// in config/environment.js

    changeTracker: {
      trackHasMany: true,
      auto: false,
      enableIsDirty: true,
    },

I'm using the latest release ember (v2.12.0) and ember-data (v2.12.1).

assertion fail when creating new record

EmberJS + EmberData 2.15

When you create a new record, you get the following assertion failure. I tried setting the changeTracker options both on the model, and in the environment.

ember-metal.js:3988 Error: Assertion Failed: You need to pass a model name to the store's serializerFor method
    at new EmberError (error.js:38)
    at Object.assert (index.js:142)
    at Class.serializerFor (-private.js:12472)
    at Function.transformFn (tracker.js:137)
    at Function.getTransform (tracker.js:261)
    at tracker.js:220
    at Array.forEach (<anonymous>)
    at Function.getTrackerInfo (tracker.js:217)
    at Function.setupTracking (tracker.js:183)
    at Class.setupTrackerMetaData (model-ext.js:47)

new record is dirty after save

It appears new records which are saved do not have their tracker data reset (via saveChanges).

Specifically in model-ext.js

  // when model updates, update the tracked state if using auto save
  saveOnUpdate: Ember.on('didUpdate', function() {
    if (Tracker.isAutoSaveEnabled(this) || Tracker.isIsDirtyEnabled(this)) {
      this.saveChanges();
    }
  }),

There would need to be another of these.

  // when model updates, update the tracked state if using auto save
  saveOnCreate: Ember.on('didCreate', function() {
    if (Tracker.isAutoSaveEnabled(this) || Tracker.isIsDirtyEnabled(this)) {
      this.saveChanges();
    }
  }),

otherwise after a new record is saved, it is still dirty due to relations being dirty.
Unless I'm missing something?

Loading lazy associations via Related Resource Links causes association to be dirty

I've managed to isolate the issue I was seeing when I commented on #28.

When an association is loaded via a related resource link and there is no data linkage for this association (i.e. missing the 'id' and 'type') then the association is considered to be changed, thus dirtying the model.

JSON API example e.g.

{
  "data": {
    "type": "project",
    "attributes": {
      "title": "Project1"
    },
    "id": 1,
    "relationships": {
      "company": {
        "links": {
          "related": "/projects/1/company"
        }
      }
    }
  }
}

I've written a breaking test for belongsTo and hasMany associations to demonstrate the problem. I'll push it to a branch shortly

Track order changes in `hasMany`

Firstly, this addon is extremely helpful! Thanks a million!

We ran into a situation where hasMany relationship items are reordered. However, the change is not recognised. I believe this is due to sorting prior to comparing arrays' items:
https://github.com/danielspaniel/ember-data-change-tracker/blob/master/addon/utilities.js#L62

We believe that the above use case is rather common when users need to reorder a list of items.

What are the advantages for sorting before comparing and is it substantial enough to outweigh the above use case?

hasDirtyAttributes does not trigger computed

computed("model.hasDirtyAttributes", {
  get() {
    // do some computing
  }
}

Does not trigger when model attributes are changed

DEBUG: -------------------------------
DEBUG: Ember             : 2.18.0
DEBUG: Ember Data        : 2.18.1
DEBUG: jQuery            : 3.3.1
DEBUG: Ember Simple Auth : 1.4.0
DEBUG: Model Fragments   : 2.14.0
DEBUG: -------------------------------

hasDirtyRelations becomes stale

model-ext.js has saveChanges() defined as:

  saveChanges(options) {
    Tracker.setupTracking(this);
    Tracker.triggerIsDirtyReset(this);
    Tracker.saveChanges(this, options);
  },

but the triggerIsDirtyReset occurs before the saveChanges, so if you have a something watching/observing isDirty, it can/might/will compute the new value of isDirty before the tracker is cleared by saveChanges.

I would suggest the order should be:

  saveChanges(options) {
    Tracker.setupTracking(this);
    Tracker.saveChanges(this, options);
    Tracker.triggerIsDirtyReset(this);
  },

This is definitely happening in our app, but I can't find an easy way to write a test in your project,
I think you would need an integration test with an hbs watching record.isDirty.

isDirty is true after save()?

Not sure if this is by design or not, but after updating a belongsTo relationship and calling save() on the model, the isDirty property is still set to true after successful request, unlike the default Ember behavior with hasDirtyAttributes.

Is there a method that needs to be called manually to use the new state as a "clean" state? I tried with saveChanges() on successful save, but to no effect.

enableIsDirty breaks when used with ember-data-model-fragments

Setting enableIsDirty whilst using ember-data-model-fragments and changing any belongsTo or hasMany relationship doesn't change any of the flags on a model.

Any changes to the relationships on a model leave the flags as false:

hasDirtyAttributes: false
hasDirtyRelations: false
isDirty: false

Removing the enableIsDirty configuration option makes the "hasDirtyAttributes" flag work again.

I'm not sure whether the problem is with ember-data-change-tracker or ember-data-model-fragments.

rollback crashes on new record.

rollback() fails on a new record.
The error is:
You must include an 'id' for oil/admin/company in an object passed to 'push'

due to:
javascript this.store.push(normalized);
at the end of the rollback function.

A weird use-case I know, have a new dialog where the user can revert back to the original state (without saving)

Working with ember-concurrency

Hello,
Is it possible to get ember-data-change-tracker to work with ember-concurrency?

The main issue I'm having is my route model attempts to load data with:

import Route from '@ember/routing/route';
import { task } from 'ember-concurrency';
export default Route.extend({
  model: function (){
    return {
      blog: this.get('blogTask').perform()
    };
  },
  blogTask: task(function *(){
    let blog = yield this.get('store').queryRecord('blog', {today:true});
    return blog;
  });
});

And then my template (via ember-concurrency) can render:

{{
input
    value=model.blog.value.name
    type="text"
    name="name"
    placeholder="Description"
}}

Am I missing something very obvious here?

Uncaught Error: Assertion Failed: [ember-data-change-tracker] changeTracker could not find...

Kind of new to emberJS here, so apologies if my issue is a trivial one. I have the following code:

export default Route.extend(MyParentRoute, {
  model(params, {queryParams}) {
    return this.modelFor('authenticated').get('premises').then((premises) => {
        ....
    });
  },
  ...
});

I wrote the following test:

test('should retrieve the correct energy account', function (assert) {
  manualSetup(this.container);
  initializer();
  const store = this.container.lookup('service:store');
  const energyAccount0 = store.createRecord('energyAccount', {id: 0});
  const energyAccount1 = store.createRecord('energyAccount', {id: 1});
  const energyAccount2 = store.createRecord('energyAccount', {id: 2});
  const premise = store.createRecord('premise', {energyAccounts: [energyAccount0, energyAccount1, energyAccount2]});
  const customer = store.createRecord('customer', {premises: [premise]});
  assert.expect(1);
  this.subject({modelFor: () => customer}).model(undefined, {queryParams: {account: 1}}).then((energyAccount) => {
    assert.deepEqual(energyAccount, energyAccount1);
  });
});

but I get the following error:

Uncaught Error: Assertion Failed: [ember-data-change-tracker] changeTracker could not find
      a undefined transform function for the attribute 'telephoneNumbers' in
      model 'customer'.
      If you are in a unit test, be sure to include it in the list of needs

I know that telephoneNumbers is an attribute of customer but I am clearly missing something here as I do not expect that error.

Is it the right approach to test the model of a route?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.