data-provider/core

Add a method for cleaning Selector dependencies cache

javierbrea opened this issue · 0 comments

The problem

Selectors theorically isolate views about the need to know its own data dependencies, but in some scenarios you want to clean a selector cache. If you use the cleanCache method, only the selector cache is cleaned, and it will be recomputed, but its dependencies will remain cached, so data will not be really refreshed. Then, you need to know which are the dependencies of a selector and clean them manually, which "breaks" the philosophy of the library.

Consider the next example, in which we have defined a selector for requesting books and authors from a REST API, then add an authorName property to the books, and then return the data:

export const booksWithAuthorName = new Selector(
  books, // Axios provider requesting data from a REST API
  authors, // Axios provider requesting data from a REST API
  (booksResponse, authorsResponse) => {
    return booksResponse.map(book => ({
      ...book,
      authorName: authors.find(author => author.id === book.author)
    }));
  }
);

Now, suposse we are using this selector in a React component, and we want to refresh data every ten seconds while the component is rendered.

THIS EXAMPLE DOESN'T WORK. With this code, only the selector cache is cleaned, so data from the selector is recalculated, but the books and authors providers are still cached and requests are not repeated:

import React, { useEffect } from "react";
import { useData } from "@data-provider/react";

import { booksWithAuthorName } from "../data/books";

const Books = () => {
  const books = useData(booksWithAuthorName);

  useEffect(() => {
      const interval = setInterval(() => {
        // Cleans the cache of the selector
        booksWithAuthorName.cleanCache();
      }, 10000);
      clearBooksInterval = () => clearInterval(interval);
    }
    return clearBooksInterval;
  }, [books]);

  return (
    <ul>
      {
        books.map((book) => {
          return (
            <li key={`book-${book.id}`}>{book.title} - {book.authorName}</li>
          );
        });
      }
    </ul>
  );
};

export default Books;

Proposed solution

Add a new cleanDependenciesCache method to Selector. Using it in the previous example, the providers cache would be also cleaned without need to know which are the selector dependencies.