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

Forward anchor state #33

Closed
Mortaro opened this issue Mar 6, 2021 · 2 comments
Closed

Forward anchor state #33

Mortaro opened this issue Mar 6, 2021 · 2 comments
Labels
enhancement New feature or request

Comments

@Mortaro
Copy link
Member

Mortaro commented Mar 6, 2021

The idea is to be able to forward anchor state directly to the next route as Ember.JS does.

tbh: I'm not sure its worth doing since it is just syntactic sugar over what context can already do.

Given an anchor like <a href="/books/1" forward={{title: 'book 1'}}> book 1 </a> the next component that matches the route would be initialized with the title = 1 in its state.

discussion:

  • the forward could be any object including nested keys
  • The forward keyword could be something else like model, state, instance and so on, please make suggestions.
  • Should it add state to all deep matched routes?
  • I suggest the lifecycle still runs normally but the user can skip unnecessary functions with the new ||= operator:
async initiate() {
   this.title ||= await this.getTitleFromServerFunction();  
}
  • It could be attached to the context on every component in the next render cycle instead of autoloaded into the state:
async initiate({ forwarded }) {
   this.title = forwarded.title || await this.getTitleFromServerFunction();  
}
@Mortaro Mortaro added the enhancement New feature or request label Mar 6, 2021
@Mortaro
Copy link
Member Author

Mortaro commented Mar 7, 2021

So far the two possible solutions me and @GuiDevloper came to are:

Explicit referral:

// referral in any link sets it to the context as is
<a href="/books/1" referral={book}>
// referral can be destructured anywhere from the context until the next anchor click replaces it
async initiate({ referral }) {
  this.book = referral || await this.getBookFromServer()
}

pro: this is very explicit
con: the code is very similar to setting an event that saves to the context and might become verbose

Implicit state

// state in a link forwards it to the next (first or all to be decided) match for the route on click
<a href="/books/1" state={{book}}>
// the component automatically receives the state before prepare is invoked
async initiate() {
  this.book ||= await this.getBookFromServer()
}

pro: you don't have to think to much about it, it is an nearly free optimization
con: it could cause problems because you are unaware of this dependency, so far Nullstack has no implicit behavior outside of the context

@Mortaro
Copy link
Member Author

Mortaro commented Mar 7, 2021

The same behavior can be achieved in a more granular way using the already implemented features of the context with the advantage of being able to cache the full list and implementing advanced features like stale while revalidate.

Ill close this issue with an example using cache + revalidation in a explicit manner that implicit state would prevent implementing:

class Books extends Nullstack {

  prepare({ project, page, cachedBooks }) {
    page.title = `Books - ${project.name}`;
    this.books = cachedBooks;
  }

  static async getBooks({ database }) {
    return await database.collection('books').find().toArray();
  }

  async initiate(context) {
    this.books = await this.getBooks();
    context.cachedBooks = data.books;
  }

}
class Book extends Nullstack {
  
  static async getBookBySlug({ database, slug }) {
    return await database.collection('books').findOne({slug});
  }

  prepare({ params, cachedBooks }) {
    this.book = cachedBooks?.find(({ slug }) => slug === params.slug);
  }

  async initiate({ params, project, page }) {
    this.book = await this.getBookBySlug({ slug: params.slug });
  }

}

@Mortaro Mortaro closed this as completed Mar 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant