Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ngx-suspense

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ngx-suspense

This library is an experimetnal implementation of React Suspense for Angular.

  • 0.0.4
  • latest
  • npm
  • Socket score

Version published
Maintainers
1
Created
Source

NgxSuspense

This library is an experimental implementation of React Suspense for Angular.

DEMO

Install the library

npm i ngx-suspense --save

Import the module:

imports: [NgxSuspenseModule];

Once you include the module, you will get following list of components you can use:

<SuspenseList revealOrder="together | forwards | backwards"></SuspenseList>
<Suspnese [fallback]="template" [bind]="suspneseServiceInstanse"></Suspnese>

and also you got one service:

NgxSuspenseService;

Usage

<Suspense>

Using [fallback] with <ng-template></ng-template>

<Suspense [fallback]="tempalteRef"><YOUR_CONTENT_FROM_SERVER /></Suspense> will use the template you passed in.

Using [bind]=suspenseServiceInstanse, allow you to bind differnet service instanse to Suspense component other than global one. Normally use [bind] when you have multi Suspsnse components inside one page.

@Component({
  selector: "categories",
  templateUrl: "./categories.component.html",
  styleUrls: ["./categories.component.scss"],
  providers: [NgxSuspenseService],
})
export class CategoriesComponent implements OnInit {
  categories$: Observable<Category[]>;
  constructor(
    private categoriesService: CategoriesService,
    private suspenseService: NgxSuspenseService
  ) {
    // Type safe
    this.categories$ = this.suspenseService.showingFor(
      this.categoriesService.getCategories()
    );

    // or
    // Side effect
    this.categories$ = this.categoriesService
      .getCategories()
      .pipe(this.suspenseService.showLoadingStatus());
  }
}
<ng-template #tmp>
  <loading-headline size="s"></loading-headline>
  <div class="column">
    <loading-headline size="m"></loading-headline>
    <loading-text size="m"></loading-text>
    <loading-text size="m"></loading-text>
  </div>
</ng-template>
<main>
  <section>
    <Suspnese [fallback]="tmp">
      <!-- Your content to be loaded below -->
      <div *ngIf="categories$ | asnyc as categories"></div>
    </Suspnese>
  </section>
</main>

In the example uses ngx-loading-skeleton for showing loading shimmer

@Input() ariaLabel: string

Support for aria-label, with default settings aria-busy=true & aria-hidden=false


<SuspenseList>

Let's say you have two or more <Suspense> inside one page.

Each of them resolve in different time, different orders, depends on network speed.

To avoid some part of UI jumping up & down, you can use <SuspenseList revealOrder="together"> as a parent component to wrap all <Suspense>s. Then all <Suspense> will resolve at the same time.

<SuspenseList revealOrder="together">
  <Suspense [fallback]="tmp1" [bind]="suspenseService1">
    <YOUR_COMPONENT1 [data]="data1$ | async" />
  </Suspense>
  <Suspense [fallback]="tmp2" [bind]="suspenseService2">
    <YOUR_COMPONENT2 [data]="data2$ | async" />
  </Suspense>
  <Suspense [fallback]="tmp3" [bind]="suspenseService3">
    <YOUR_COMPONENT3 [data]="data3$ | async" />
  </Suspense>
</SuspenseList>
class YOUR_SMART_COMPONENT {
    this.suspenseService1 = new NgxSuspenseService()
    this.suspenseService2 = new NgxSuspenseService()
    this.suspenseService3 = new NgxSuspenseService()

    this.data1$ = this.apiService.loadData1()
        .pipe(
            this.suspenseService1.showLoadingStatus()
        )
    this.data2$ = this.apiService.loadData2()
        .pipe(
            this.suspenseService2.showLoadingStatus()
        )
    this.data3$ = this.apiService.loadData3()
        .pipe(
            this.suspenseService3.showLoadingStatus()
        )
}

NgxSuspenseService

showingFor<T>(Obs$: Observable<T>): Observable<T>

You can pass in an observable which will finially complete, showingFor will trigger the side effect which control loading spinner ON / OFF. Type friendly approach.

Example:

@Component({
  selector: "categories",
  templateUrl: "./categories.component.html",
  styleUrls: ["./categories.component.scss"],
  providers: [NgxSuspenseService],
})
export class CategoriesComponent implements OnInit {
  categories$: Observable<Category[]>;
  constructor(
    private categoriesService: CategoriesService,
    private suspenseService: NgxSuspenseService
  ) {
    this.categories$ = this.suspenseService.showingFor(
      this.categoriesService.getCategories()
    );
  }
}
showLoadingStatus()

The same effect with showingFor(), just doesn't have type information.

this.categories$ = this.categoriesService
  .getCategories()
  .pipe(this.suspenseService.showLoadingStatus());
show() / hide()

If you wish to have normal control flow approach. You can use show / hide

this.suspenseService.show();
await this.apiService.load();
this.suspenseService.hide();

Configuration

You can set busyDelayMs and busyMinDurationMs.

imports: [
  NgxSuspenseModule.forRoot({
    busyDelayMs: 300, // within 300ms, don't show the loading skeleton; default value: 0
    busyMinDurationMs: 700, // showing loading skeleton for at least 700ms; default value: 0
  }),
];

Keywords

FAQs

Package last updated on 28 Jun 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc