question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Does / should `revertData` have old data as well?

See original GitHub issue

In the examples shown for revertData in the optimistic data updates, I find that it takes only one parameter and that parameter is the latest local data (after updateDataOptimistic has run).

For a use case where I am trying to edit some resource, I run into this issue where I am not able to revertData unless I also pass the older data down.

Example:

const editBook = (editedBook) => ({
  type: EDIT_BOOK_OPTIMISTIC,
  request: {
    url: `/book/${editedBook.id}`,
    method: 'PUT',
  },
  meta: {
    mutations: {
      FETCH_BOOKS: {
        updateDataOptimistic: data => data.map(d => d.id === editedBook.id ? editedBook : d),
        revertData: data => ???
      }
    }
  }
})

In this case’s revertData, I need access to old/previous data for the given book which is being edited.

Is this already available (and I am missing it)? Or, if it’s not available and the only solution is to pass the older data down to the dispatch action (like editBook = (editedBook, oldBook))), is it possible to add the previous data as the second arg to revertData?

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:22 (15 by maintainers)

github_iconTop GitHub Comments

1reaction
klis87commented, Dec 30, 2020

We also match redux-saga, apart from queue/concatMap, I believe this would be needed to implement on user land in sagas. Anyway, what I think is this:

  • takeEvery/mergeMap is perfect when order doesn’t matter, in my opinion this is usually good for mutations, but bad for queries
  • takeLatest/switchMap is usually the best for queries, perfect for things like typehead, pagination, so you prevent race conditions and you don’t waste resources, bad very bad for mutations, maybe unless we don’t care about mutation responses in some cases
  • concatMap is perfect for mutations with optimistic updates, queueing actually doesnt hurt perceived performance thanks to optimistic updates!
  • takeLeading/exhaustMap - this is really needed for SSR and queries, and on the client it would be cool for queries without variables and perhaps for mutations which are rather single at a moment, to prevent redundant liking of an already liked entity and so on

For now we support takeLatest and takeEvery. TakeLatest is the default for queries and takeEvery for mutations, but I am pretty sure that defaults could be set dynamically depending on circumstances, like described above. Then defaults would be sensibly chosen, but always possible to override

1reaction
klis87commented, Dec 29, 2020

This was my first thought when I started playing with updateDataOptimistic but I felt that that would be becoming too opinionated.

I am wondering, maybe an option like meta.autoRevert: true could achieve this behaviour? The point is, the most common use case indeed is to revert just to… old data. Sometimes it is possible to calculate previous data by decrementing and so on (to provide a mathematically reverse operation in comparison to updateDataOptimistic), but I don’t think all cases could handle race conditions. Maybe sometimes it is just better to remove any possibility of such issues by removing parallelism.

Now, UI fires one more request (R#2) before there is any response for R#1. Given takeLeading: true, does the UI update optimistically again?

No, because R#2 would just join R#1, no 2nd request would not be fired at all, and promise of dispatched R2 would resolve with the same as R1

If you use updateDataOptimistic and revertData in your request X, the library will automatically queue the requests of type X so at any given point of time, revertData’s oldData is always the last-non-stale copy of your store just before request X was made.

This is a very good idea, I think this is yet another effect, like takeQueued. This would indeed solve parallel requests issues, reverting would work fine as all would be in a sequence.

Regarding takeLeading, this would work for a mutations with the very same variables, for example imagine a silly example like likePost mutation, and imagine it is fired like that:

  1. data.liked is false initially
  2. R1 is fired, data.liked is optimistically set to true, oldData is false
  3. R2 is fired, duplicating the 2), but fired anyway, both new data and old data liked is true
  4. R2 succeedded, data.liked is still true
  5. R1 failes, data.liked is incorrectly reverted to false! R2 was a success, so post was liked!

Take leading would solve this as R2 wouldn’t be fired at all. However, if likePost could have variables like id, then takeLeading would make issues as likePost(1), likePost(2) would ignore liking of post 2 incorrectly. But then, together with meta.requestKey: id, this would again work!

Queues would also help in this scenario, even without requestKey, but performance would be worse as requests couldn’t be fired at once.

To sum up, in my opinion this library should provide sensible defaults and to have enough declarative configuration so any real-life case like above could be handled with a set of properties, for example mixture of an effect and requestKey

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to bubble up meaningful 0x contract revert data?
Is there any way to get meaningful error data from the swapTarget.call{value: msg.value}(swapCallData); call? I should mention that I'm using a ...
Read more >
revert data (fetched and checked-out) to pointers after git lfs ...
Hi, after a git clone the files are stored as text pointer, using then lfs fetch and lfs checkout the original files are...
Read more >
Revert throws "missing revert data" in inherited method
From the stack trace, it appears that the revert is caused by an external call. The only external call here is the coll.existsAttrib...
Read more >
REVERT-DATA MANAGEMENT PLAN_en_v1.5
ABSTRACT. A document summarizing the way in which the data will be managed inside the REVERT ecosystem, from. REVERT partner and third parties....
Read more >
Building a data warehouse in the cloud using Snowflake
Snowflake has customizable warehouses (compute nodes) that can be ... the ability to look back in time or revert data to an older...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found