react-rethinkdb icon indicating copy to clipboard operation
react-rethinkdb copied to clipboard

Replacing subscribed data on change

Open jerrygreen opened this issue 9 years ago • 2 comments

The main essence is that I'm getting duplicates of the same objects in this.data. One is actual (with new values), another is not. Changed object is placed at the end of array but old object not removed.

I found this code:

        var oldIndex = -1;
        if (oldVal) {
          (function () {
            var lookup = JSON.stringify(oldVal);
            oldIndex = (0, _utilJs.findIndex)(_this4.value, function (x) {
              return JSON.stringify(x) === lookup;
            });
          })();
        }

In my case the returned value of comparison should be true but I got false coz the values was little bit different:

{"agents":[{"first_name":"Bilbo","last_name":"Baggins"}],"awaiting_from":"2016-11-22T13:07:00.395Z","customer":{"name":"1068916776508564q","tags":[{"id":48,"name":"customer_tag_3"},{"id":3,"name":"customer_tag_1"}]},"id":20232,"last_message":{"channel":{"name":"Facebook"},"created_at":"2016-11-14T11:01:50.758Z","id":1577651,"inbound":false,"text":"Hello, it's a custom message from Postman.","updated_at":"2016-11-14T11:01:51.531Z","user_id":4},"last_reminder":{"text":"test reminder","time":"2016-11-22T13:07:00.033Z"},"status":"new_message","tags":[{"id":5,"name":"conversation_tag_1"},{"id":6,"name":"conversation_tag_2"}]}
{"agents":[{"first_name":"Bilbo","last_name":"Baggins"}],"awaiting_from":"2016-11-22T13:07:00.395Z","customer":{"name":"1068916776508564q","tags":[{"id":48,"name":"customer_tag_3"},{"id":3,"name":"customer_tag_1"}]},"id":20232,"last_message":{"channel":{"name":"Facebook"},"created_at":"2016-11-14T11:01:50.758Z","id":1577651,"inbound":false,"text":"Hello, it's a custom message from Postman.","updated_at":"2016-11-14T11:01:51.531Z","user_id":4},"last_reminder":{"text":"test reminder","time":"2016-11-22T13:07:00.033Z","created_at":"2016-11-22T13:07:00.033Z"},"status":"new_message","tags":[{"id":5,"name":"conversation_tag_1"},{"id":6,"name":"conversation_tag_2"}]}

I have just changed QueryState.js to my specific case:

        var oldIndex = -1;
        if (oldVal) {
          (function () {
            // var lookup = JSON.stringify(oldVal);
            oldIndex = (0, _utilJs.findIndex)(_this4.value, function (x) {
              // return JSON.stringify(x) === lookup;
              return x.id === oldVal.id;
            });
          })();
        }

It works perfectly and faster (no performance tests though, lol) but requires presence of id (which should be an identificator). I think you could implement some feature to have (optionally) your identificator fieldname in observe to use this comparison without stringifying full object (and recommend to use it). Or, at least, to find how this bug appear and how it is possible to receive different objects in this case. Maybe it is fixable (I think so but too lazy to debug more).

jerrygreen avatar Dec 14 '16 18:12 jerrygreen

Interesting! I agree that using id is better, but I had assumed that oldVal would always be identical to the object that was already in the list, so just left the stringify in since there's no requirement that documents have unique keys.

I diffed the two objects you outputted, and the only difference was the second object defined last_reminder.created_at and the first object left it undefined. Is there anything different about the way you're populating that field than the others?

mikemintz avatar Dec 21 '16 22:12 mikemintz

@mikemintz no, at least I don't see any relevant difference. This works as expected in casual cases. But I don't know why my case is unusual.

Btw I think you can easily force people to use id for every document in a new version. That's not bad.

jerrygreen avatar Dec 22 '16 09:12 jerrygreen