title: Store and update the api data into local storage for fast prerendering pages
body: <p>I'm building a bitcoin chart by Angular 4 universal integrated with asp.net core. I made http requests from api endpoints (<a href="https://www.coindesk.com/api/" rel="nofollow noreferrer">https://www.coindesk.com/api/</a>) which returned the data to visualize a chart. Everytime I reload the page, the chart display is always delayed around 1-2 seconds because it pulls data from server. I want to ask other solutions to prevent this, the main purpose is to make the chart fast pre-rendering as the same as plain texts on template. Therefore, I'm thinking about storing the api data into local storage, so reloading the page pulls data from local storage that make fast rendering. Is it possible to do that?</p>
  
  <p>Here are my current codes:</p>
  
  <p>historical-bpi.service.ts: </p>
  
  <pre><code>import { Injectable } from '@angular/core';
  import { Http } from '@angular/http';
  import 'rxjs/add/operator/map';
  
  @Injectable()
  export class HistoricalBpiService {
  
    private JsonBaseUrl: string = 'https://api.coindesk.com/v1/bpi/';
  
    constructor(private http:Http) { }
  
    getBpiData(url: string){
      return this.http.get(this.JsonBaseUrl+url)
        .map(res =&gt; res.json());
    }
  }
  </code></pre>
  
  <p>component ts:</p>
  
  <pre><code>import { Component, OnInit, Inject, PLATFORM_ID } from '@angular/core';
  import { HistoricalBpiService } from '../../services/historical-bpi.service';
  import { isPlatformBrowser, isPlatformServer } from '@angular/common';
  import * as moment from 'moment';
  
  @Component({
    selector: 'app-banner',
    templateUrl: './banner.component.html',
    styleUrls: ['./banner.component.scss']
  })
  export class BannerComponent implements OnInit {
  
    private isDataAvailable: boolean;
  
    // Define date options
    private today: string = moment().format('YYYY-MM-DD');
    private oneYearAgo: string = moment().subtract(1,'years').format('YYYY-MM-DD');
    private nineMonthsAgo: string = moment().subtract(9,'months').format('YYYY-MM-DD');
  
    private oneYearData: string = 'historical/close.json?start=' + this.oneYearAgo + '&amp;end=' + this.today;
    private nineMonthsData: string = 'historical/close.json?start=' + this.nineMonthsAgo + '&amp;end=' + this.today;      
  
    // API calls for the date options
    oneYear() {
      this.historicalBpiService.getBpiData(this.oneYearData)
        .subscribe(
          res =&gt; {
            this.lineChartData[0].data = Object.keys(res.bpi).map(function (key) { return res.bpi[key]; });
            this.lineChartLabels = Object.keys(res.bpi);
            this.isDataAvailable = true;
          }
        )
    }
  
    nineMonths() {
      this.historicalBpiService.getBpiData(this.nineMonthsData)
        .subscribe(
          res =&gt; {
            this.lineChartData[0].data = Object.keys(res.bpi).map(function (key) { return res.bpi[key]; });
            this.lineChartLabels = Object.keys(res.bpi);
          }
        )
    }      
  
    constructor(
      private historicalBpiService:HistoricalBpiService,
      @Inject(PLATFORM_ID) private platformId: Object
    ) {}
  
    // lineChart
  
    public lineChartData:any = [
      { data:[], label: 'BTC' }
    ];
  
    public lineChartLabels:Array&lt;any&gt; = [];
  
    public lineChartOptions:any = {
      responsive: true,
      maintainAspectRatio: false,
      layout: {
        padding: 0
      },        
      scales: {
        yAxes: [{
          display: false,
          scaleLabel: {
            display: false,
            labelString: 'USD'
          },            
          gridLines: {
            display: true,
            tickMarkLength: 0
          }
        }],
        xAxes: [{
          ticks: {
            display: false,
            mirror: true
          }          
        }]
      },
      elements: {
        point: {
          radius: 0
        },
        line: {
          tension: 0, // 0 disables bezier curves
        }
      },
      hover: {
        mode: 'label',
        intersect: false
      },
      tooltips: {
        mode: 'label',
        intersect: false,
        backgroundColor: 'rgb(95,22,21)'          
      }
    };
    public lineChartColors:Array&lt;any&gt; = [
      {
        backgroundColor: 'rgba(199,32,48,1)',
        //borderColor: 'rgb(95,22,21)',
        pointHoverBackgroundColor: 'rgba(218,208,163,1)',
        steppedLine: false
      }
    ];
    public lineChartLegend:boolean = false;
    public lineChartType:string = 'line';    
  
    // events
    public chartClicked(e:any):void {
      console.log(e);
    }
  
    public chartHovered(e:any):void {
      console.log(e);
    }
  
    ngOnInit(){
      if (isPlatformBrowser(this.platformId)) {
        // Default chart
        this.oneYear();
      }
    }
  }
  </code></pre>
  
  <p>component html:</p>
  
  <pre><code>&lt;div class="chart"&gt;
        &lt;canvas baseChart height="360px"
          [datasets]="lineChartData"
          [labels]="lineChartLabels"
          [options]="lineChartOptions"
          [colors]="lineChartColors"
          [legend]="lineChartLegend"
          [chartType]="lineChartType"
          (chartHover)="chartHovered($event)"
          (chartClick)="chartClicked($event)"&gt;
        &lt;/canvas&gt;
      &lt;/div&gt;
      &lt;div class="d-flex justify-content-end dateOptions" *ngIf="isDataAvailable"&gt;      
        &lt;input type="radio" name="Button" class="ButtonState" checked id="9months"/&gt;
        &lt;label class="Button" for="9months" (click)="nineMonths()"&gt;9 Months&lt;/label&gt;
        &lt;input type="radio" name="Button" class="ButtonState" checked id="1year"/&gt;
        &lt;label class="Button" for="1year" (click)="oneYear()"&gt;1 Year&lt;/label&gt;
      &lt;/div&gt;
  </code></pre>