npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ionic-cache-observable

v0.0.6

Published

Ionic cache service to sync observables with local storage.

Downloads

37

Readme

ionic-offline-observable

Simple module to cache observables to local storage and get or refresh their values across your app. This improves performance by only executing observables once, and allows your app to show the cached content when offline or before content is loaded on a slow connection.

Installation

Install the package:

npm install --save ionic-cache-observable

Import in your project app.module.ts:

@NgModule({
    imports: [
        IonicModule.forRoot(App),
        IonicStorageModule.forRoot(),
        CacheModule,
        ...
    ]
})

Blog post

Read about using the module or try out the sample Ionic app on Medium.

Usage example

You have a page, ShoppingListPage, that shows the user's shoppinglist. The shopping list is normally retrieved from your server with your ShoppingListProvider service.

With the implementation below, it is either retrieved by local storage OR from the provider.

constructor(private cacheService: CacheService,
            private shoppingListProvider: ShoppingListProvider) { }

ionViewWillEnter() {
    // The observable you normally get items from server with.
    let shoppingListObservable: Observable<ShoppingList> = this.shoppingListProvider.get();

    this.cacheService
        .register('shoppingList', shoppingListObservable)
        .mergeMap((cache: Cache<ShoppingList>) => cache.get())
        .subscribe((shoppingList) => {
          // The shopping list is retrieved from local storage,
          // or in the case that it doesn't exist in storage yet;
          // by triggering your shoppingListObservable.
          this.shoppingList = shoppingList;
        });

}

refreshShoppingList() {
    this.cacheService
        .get('shoppingList')
        .mergeMap((cache: Cache<ShoppingList>) => cache.refresh())
        .subscribe((shoppingList) => {
          // The shopping list was just "refreshed" by calling the
          // shoppingListProvider observable that was registered with the cache.
          this.shoppingList = shoppingList;
        });    
}

A more flexible approach is to use the BehaviorSubject. This also allows you to easily refresh and get the cached shopping list at the same time:

private cache: Cache<ShoppingList>;

private cacheSubscription: Subscription;

ionViewWillEnter() {
    this.cacheSubscription = this.cacheService
        .register('shoppingList', shoppingListObservable)
        .mergeMap((cache: Cache<ShoppingList>) => {
            this.cache = cache;
            
            // We can call refresh already. The refreshed value will be 
            // passed to the get$ BehaviorSubject.
            this.cache.refresh().subscribe();
            
            return this.cache.get$;
        }).subscribe((shoppingList) => {
            // This is a long-lived Observable that will be triggered when the 
            // Cache is first initialized with the locally stored value,
            // and whenever refresh is called.
        
            this.shoppingList = shoppingList;
        });
}

refreshShoppingList() {
    // Just call refresh, the cacheSubscription takes care of the rest.
    this.cache.refresh().subscribe();    
}

Make sure to unsubscribe when needed, ie in ionViewWillLeave.

Functionality

  1. Keep in mind: When registering a Cache, it will immediately load the locally stored value to memory.

  2. Cache.isEmpty can be used to determine if the cache has a value. If it is empty, it will automatically try to refresh.

  3. NULL values can be a problem in determining if the cache is empty and should be refreshed.

  4. Depending on your application flow, use CacheService.register or CacheService.get.

    1. If you need to use the same Cache object on multiple pages, you can either register it globally first (ie your AppComponent, app.ts) and get it on all the pages.
    2. Or you can register the same cache multiple times. It is perfectly legal and will not invalidate existing cache objects, simply update its internal Observable, unless the overwrite parameter is set to false register(name, false).
    3. But don't register the same cache with a completely different observable, and don't get caches that hasn't been registered.
  5. Advanced usage might have you re-registering the cache with a more detailed observable.

    1. First it's registered with shoppingListProvider.get()
    2. On a deeper page, you can re-register with shoppingListProvider.get({include: 'users'}), because that page needs the the shopping list's owners.
    3. The deeper page would first display the cached value (without owners) and then when the refreshed value arrives, add the user info.

Contribution

This is just something I threw together quickly because I needed a simple, reusable solution to support offline apps.

However, I will maintain the project and welcome any contributions.