Completed Cache
This commit is contained in:
parent
f6735a38fe
commit
d875c033d9
BIN
API/wwwroot/images/products/ABS-Gladiator-Gaming-PC-1749.jpg
Normal file
BIN
API/wwwroot/images/products/ABS-Gladiator-Gaming-PC-1749.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 100 KiB |
Binary file not shown.
After Width: | Height: | Size: 77 KiB |
Binary file not shown.
After Width: | Height: | Size: 96 KiB |
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
After Width: | Height: | Size: 107 KiB |
Binary file not shown.
After Width: | Height: | Size: 80 KiB |
@ -1,26 +1,26 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"Id": 1,
|
"Id": 1,
|
||||||
"Name": "Angular"
|
"Name": "ABS"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 2,
|
"Id": 2,
|
||||||
"Name": "NetCore"
|
"Name": "Cyberpower"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 3,
|
"Id": 3,
|
||||||
"Name": "VS Code"
|
"Name": "Skytech"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 4,
|
"Id": 4,
|
||||||
"Name": "React"
|
"Name": "Velztorm"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 5,
|
"Id": 5,
|
||||||
"Name": "Typescript"
|
"Name": "Bose"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 6,
|
"Id": 6,
|
||||||
"Name": "Redis"
|
"Name": "Beats"
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -1,51 +1,51 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"Name": "Angular Speedster Board 2000",
|
"Name": "ABS Gladiator Gaming PC",
|
||||||
"Description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.",
|
"Description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.",
|
||||||
"Price": 200,
|
"Price": 1749,
|
||||||
"PictureUrl": "images/products/sb-ang1.png",
|
"PictureUrl": "images/products/ABS-Gladiator-Gaming-PC-1749.jpg",
|
||||||
"ProductTypeId": 1,
|
"ProductTypeId": 1,
|
||||||
"ProductBrandId": 1
|
"ProductBrandId": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Green Angular Board 3000",
|
"Name": "CyberpowerPC Gaming Desktop Gamer Master",
|
||||||
"Description": "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.",
|
"Description": "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.",
|
||||||
"Price": 150,
|
"Price": 1699,
|
||||||
"PictureUrl": "images/products/sb-ang2.png",
|
"PictureUrl": "images/products/CyberpowerPC-Gaming-Desktop-Gamer-Master-1699.jpg",
|
||||||
"ProductTypeId": 1,
|
"ProductTypeId": 1,
|
||||||
"ProductBrandId": 1
|
"ProductBrandId": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Core Board Speed Rush 3",
|
"Name": "Skytech Archangel 3.0 Gaming Computer PC Desktop",
|
||||||
"Description": "Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc. Mauris eget neque at sem venenatis eleifend. Ut nonummy.",
|
"Description": "Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc. Mauris eget neque at sem venenatis eleifend. Ut nonummy.",
|
||||||
"Price": 180,
|
"Price": 1199,
|
||||||
"PictureUrl": "images/products/sb-core1.png",
|
"PictureUrl": "images/products/Skytech-Archangel-3.0-Gaming-Computer-PC-Desktop-1199.jpg",
|
||||||
"ProductTypeId": 1,
|
"ProductTypeId": 1,
|
||||||
"ProductBrandId": 2
|
"ProductBrandId": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Net Core Super Board",
|
"Name": "Velztorm Nix Custom Built Gaming Desktop PC",
|
||||||
"Description": "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.",
|
"Description": "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.",
|
||||||
"Price": 300,
|
"Price": 1449,
|
||||||
"PictureUrl": "images/products/sb-core2.png",
|
"PictureUrl": "images/products/Velztorm-Nix-Custom-Built-Gaming-Desktop-PC-1449.jpg",
|
||||||
"ProductTypeId": 1,
|
|
||||||
"ProductBrandId": 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "React Board Super Whizzy Fast",
|
|
||||||
"Description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.",
|
|
||||||
"Price": 250,
|
|
||||||
"PictureUrl": "images/products/sb-react1.png",
|
|
||||||
"ProductTypeId": 1,
|
"ProductTypeId": 1,
|
||||||
"ProductBrandId": 4
|
"ProductBrandId": 4
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Typescript Entry Board",
|
"Name": "ABS Legend Gaming PC - Intel i9 12900K",
|
||||||
"Description": "Aenean nec lorem. In porttitor. Donec laoreet nonummy augue.",
|
"Description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.",
|
||||||
"Price": 120,
|
"Price": 4149,
|
||||||
"PictureUrl": "images/products/sb-ts1.png",
|
"PictureUrl": "images/products/ABS-Legend-Gaming-PC-Intel-i9-12900K.jpg",
|
||||||
"ProductTypeId": 1,
|
"ProductTypeId": 1,
|
||||||
"ProductBrandId": 5
|
"ProductBrandId": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Skytech Chronos Gaming PC Desktop",
|
||||||
|
"Description": "Aenean nec lorem. In porttitor. Donec laoreet nonummy augue.",
|
||||||
|
"Price": 1599,
|
||||||
|
"PictureUrl": "images/products/Skytech-Chronos-Gaming-PC-Desktop.jpg",
|
||||||
|
"ProductTypeId": 1,
|
||||||
|
"ProductBrandId": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Core Blue Hat",
|
"Name": "Core Blue Hat",
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"Id": 1,
|
"Id": 1,
|
||||||
"Name": "Boards"
|
"Name": "Computers"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 2,
|
"Id": 2,
|
||||||
"Name": "Hats"
|
"Name": "Headphones"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 3,
|
"Id": 3,
|
||||||
"Name": "Boots"
|
"Name": "Gadgets"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 4,
|
"Id": 4,
|
||||||
"Name": "Gloves"
|
"Name": "Accessories"
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -1,3 +1,3 @@
|
|||||||
# SkiNet
|
# SkyNet
|
||||||
|
|
||||||
Built upon ASP.NET, Angular, Bootstrap, and Stripe for Credit Card Processing!
|
Built upon ASP.NET, Angular, Bootstrap, and Stripe for Credit Card Processing!
|
@ -8,7 +8,7 @@ import { AccountService } from './account/account.service';
|
|||||||
styleUrls: ['./app.component.scss']
|
styleUrls: ['./app.component.scss']
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit {
|
||||||
title = 'SkiNet';
|
title = 'SkyNet';
|
||||||
|
|
||||||
constructor(private basketService: BasketService, private accountService: AccountService) {}
|
constructor(private basketService: BasketService, private accountService: AccountService) {}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
[boundaryLinks]="true"
|
[boundaryLinks]="true"
|
||||||
[totalItems]="totalCount"
|
[totalItems]="totalCount"
|
||||||
(pageChanged)="onPagerChange($event)"
|
(pageChanged)="onPagerChange($event)"
|
||||||
|
[ngModel]="pageNumber"
|
||||||
[itemsPerPage]="pageSize"
|
[itemsPerPage]="pageSize"
|
||||||
previousText="‹"
|
previousText="‹"
|
||||||
nextText="›"
|
nextText="›"
|
||||||
|
@ -8,6 +8,7 @@ import { Component, EventEmitter, Input, Output, OnInit } from '@angular/core';
|
|||||||
export class PagerComponent implements OnInit {
|
export class PagerComponent implements OnInit {
|
||||||
@Input() totalCount: number;
|
@Input() totalCount: number;
|
||||||
@Input() pageSize: number;
|
@Input() pageSize: number;
|
||||||
|
@Input() pageNumber: number;
|
||||||
@Output() pageChanged = new EventEmitter<number>();
|
@Output() pageChanged = new EventEmitter<number>();
|
||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
import { IProduct } from "./product"
|
import { IProduct } from "./product"
|
||||||
|
|
||||||
export interface IPagination {
|
export interface IPagination {
|
||||||
pageIndex: number
|
pageIndex: number;
|
||||||
pageSize: number
|
pageSize: number;
|
||||||
count: number
|
count: number;
|
||||||
data: IProduct[]
|
data: IProduct[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class Pagination implements IPagination {
|
||||||
|
pageIndex: number;
|
||||||
|
pageSize: number;
|
||||||
|
count: number;
|
||||||
|
data: IProduct[] = [];
|
||||||
|
}
|
||||||
|
@ -29,6 +29,7 @@ import { RouterModule } from '@angular/router';
|
|||||||
CarouselModule.forRoot(),
|
CarouselModule.forRoot(),
|
||||||
BsDropdownModule.forRoot(),
|
BsDropdownModule.forRoot(),
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
|
FormsModule,
|
||||||
CdkStepperModule,
|
CdkStepperModule,
|
||||||
RouterModule
|
RouterModule
|
||||||
],
|
],
|
||||||
@ -40,6 +41,7 @@ import { RouterModule } from '@angular/router';
|
|||||||
OrderTotalsComponent,
|
OrderTotalsComponent,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
|
FormsModule,
|
||||||
BsDropdownModule,
|
BsDropdownModule,
|
||||||
TextInputsComponent,
|
TextInputsComponent,
|
||||||
CdkStepperModule,
|
CdkStepperModule,
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
<h5 class="text-warning ml-3">Sort</h5>
|
<h5 class="text-warning ml-3">Sort</h5>
|
||||||
<select class="form-select mb-3" style="width: 100%;" (change)="onSortSelected($event.target.value)">
|
<select class="form-select mb-3" style="width: 100%;" (change)="onSortSelected($event.target.value)">
|
||||||
<option *ngFor="let sort of sortOptions"
|
<option *ngFor="let sort of sortOptions"
|
||||||
|
[selected]="shopParams.sort === sort.value"
|
||||||
[value]="sort.value"
|
[value]="sort.value"
|
||||||
>
|
>
|
||||||
{{sort.name}}
|
{{sort.name}}
|
||||||
@ -57,6 +58,7 @@
|
|||||||
<app-pager
|
<app-pager
|
||||||
[pageSize]="shopParams.pageSize"
|
[pageSize]="shopParams.pageSize"
|
||||||
[totalCount]="totalCount"
|
[totalCount]="totalCount"
|
||||||
|
[pageNumber]="shopParams.pageNumber"
|
||||||
(pageChanged)="onPageChange($event)"
|
(pageChanged)="onPageChange($event)"
|
||||||
></app-pager>
|
></app-pager>
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,7 +15,7 @@ export class ShopComponent implements OnInit {
|
|||||||
products: IProduct[];
|
products: IProduct[];
|
||||||
brands: IBrand[];
|
brands: IBrand[];
|
||||||
productType: IType[];
|
productType: IType[];
|
||||||
shopParams = new ShopParams();
|
shopParams: ShopParams;
|
||||||
totalCount: number;
|
totalCount: number;
|
||||||
sortOptions = [
|
sortOptions = [
|
||||||
{name: 'Name', value: 'name'},
|
{name: 'Name', value: 'name'},
|
||||||
@ -23,21 +23,21 @@ export class ShopComponent implements OnInit {
|
|||||||
{name: 'Price: High to Low', value: 'priceDesc'}
|
{name: 'Price: High to Low', value: 'priceDesc'}
|
||||||
];
|
];
|
||||||
|
|
||||||
constructor(private shopService: ShopService) { }
|
constructor(private shopService: ShopService) {
|
||||||
|
this.shopParams = this.shopService.getShopParams();
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.getProducts();
|
this.getProducts(true);
|
||||||
this.getBrands();
|
this.getBrands();
|
||||||
this.getTypes();
|
this.getTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
getProducts(){
|
getProducts(useCache = false){
|
||||||
this.shopService.getProducts(this.shopParams).subscribe(
|
this.shopService.getProducts(useCache).subscribe(
|
||||||
{
|
{
|
||||||
next: (response) => {
|
next: (response) => {
|
||||||
this.products = response.data;
|
this.products = response.data;
|
||||||
this.shopParams.pageNumber = response.pageIndex;
|
|
||||||
this.shopParams.pageSize = response.pageSize;
|
|
||||||
this.totalCount = response.count;
|
this.totalCount = response.count;
|
||||||
},
|
},
|
||||||
error: (e: any) => { console.log(e); },
|
error: (e: any) => { console.log(e); },
|
||||||
@ -67,38 +67,49 @@ export class ShopComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onBrandSelected(brandId: number){
|
onBrandSelected(brandId: number){
|
||||||
this.shopParams.brandId = brandId;
|
const params = this.shopService.getShopParams();
|
||||||
this.shopParams.pageNumber = 1;
|
params.brandId = brandId;
|
||||||
|
params.pageNumber = 1;
|
||||||
|
this.shopService.setShopParams(params);
|
||||||
this.getProducts();
|
this.getProducts();
|
||||||
}
|
}
|
||||||
|
|
||||||
onTypeSelected(typeId: number){
|
onTypeSelected(typeId: number){
|
||||||
this.shopParams.typeId = typeId;
|
const params = this.shopService.getShopParams();
|
||||||
this.shopParams.pageNumber = 1;
|
params.typeId = typeId;
|
||||||
|
params.pageNumber = 1;
|
||||||
|
this.shopService.setShopParams(params);
|
||||||
this.getProducts();
|
this.getProducts();
|
||||||
}
|
}
|
||||||
|
|
||||||
onSortSelected(sort: string){
|
onSortSelected(sort: string){
|
||||||
this.shopParams.sort = sort;
|
const params = this.shopService.getShopParams();
|
||||||
|
params.sort = sort;
|
||||||
|
this.shopService.setShopParams(params);
|
||||||
this.getProducts();
|
this.getProducts();
|
||||||
}
|
}
|
||||||
|
|
||||||
onPageChange(e: any){
|
onPageChange(e: any){
|
||||||
if (this.shopParams.pageNumber !== e){
|
const params = this.shopService.getShopParams();
|
||||||
this.shopParams.pageNumber = e;
|
if (params.pageNumber !== e){
|
||||||
this.getProducts();
|
params.pageNumber = e;
|
||||||
|
this.shopService.setShopParams(params);
|
||||||
|
this.getProducts(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onSearch(){
|
onSearch(){
|
||||||
this.shopParams.search = this.searchTerm.nativeElement.value;
|
const params = this.shopService.getShopParams()
|
||||||
this.shopParams.pageNumber = 1;
|
params.search = this.searchTerm.nativeElement.value;
|
||||||
|
params.pageNumber = 1;
|
||||||
|
this.shopService.setShopParams(params);
|
||||||
this.getProducts();
|
this.getProducts();
|
||||||
}
|
}
|
||||||
|
|
||||||
OnReset(){
|
OnReset(){
|
||||||
this.searchTerm.nativeElement.value = '';
|
this.searchTerm.nativeElement.value = '';
|
||||||
this.shopParams = new ShopParams();
|
this.shopParams = new ShopParams();
|
||||||
|
this.shopService.setShopParams(this.shopParams);
|
||||||
this.getProducts();
|
this.getProducts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,56 +1,108 @@
|
|||||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { IBrand } from '../shared/models/brand';
|
import { IBrand } from '../shared/models/brand';
|
||||||
import { IPagination } from '../shared/models/pagination';
|
import { IPagination, Pagination } from '../shared/models/pagination';
|
||||||
import { IType } from '../shared/models/producttype';
|
import { IType } from '../shared/models/producttype';
|
||||||
import { map } from 'rxjs/operators'
|
import { map } from 'rxjs/operators'
|
||||||
import { ShopParams } from '../shared/models/shopparams';
|
import { ShopParams } from '../shared/models/shopparams';
|
||||||
import { IProduct } from '../shared/models/product';
|
import { IProduct } from '../shared/models/product';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class ShopService {
|
export class ShopService {
|
||||||
baseURL = 'https://localhost:5001/api/'
|
baseURL = 'https://localhost:5001/api/';
|
||||||
|
products: IProduct[] = [];
|
||||||
|
brands: IBrand[] = [];
|
||||||
|
types: IType[] = [];
|
||||||
|
pagination = new Pagination();
|
||||||
|
shopParams = new ShopParams();
|
||||||
|
productCache = new Map();
|
||||||
|
|
||||||
constructor(private http: HttpClient) { }
|
constructor(private http: HttpClient) { }
|
||||||
|
|
||||||
getProducts(shopParams: ShopParams){
|
getProducts(useCache: boolean){
|
||||||
|
if (useCache === false){
|
||||||
|
this.productCache = new Map();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.productCache.size > 0 && useCache === true){
|
||||||
|
if(this.productCache.has(Object.values(this.shopParams).join('-'))) {
|
||||||
|
this.pagination.data = this.productCache.get(Object.values(this.shopParams).join('-'));
|
||||||
|
return of(this.pagination);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let params = new HttpParams();
|
let params = new HttpParams();
|
||||||
|
|
||||||
if (shopParams.brandId !== 0){
|
if (this.shopParams.brandId !== 0){
|
||||||
params = params.append('brandId', shopParams.brandId.toString());
|
params = params.append('brandId', this.shopParams.brandId.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(shopParams.typeId !== 0){
|
if(this.shopParams.typeId !== 0){
|
||||||
params = params.append('typeId', shopParams.typeId.toString());
|
params = params.append('typeId', this.shopParams.typeId.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shopParams.search){
|
if (this.shopParams.search){
|
||||||
params = params.append('search', shopParams.search);
|
params = params.append('search', this.shopParams.search);
|
||||||
}
|
}
|
||||||
|
|
||||||
params = params.append('sort', shopParams.sort);
|
params = params.append('sort', this.shopParams.sort);
|
||||||
params = params.append('pageIndex', shopParams.pageNumber.toString());
|
params = params.append('pageIndex', this.shopParams.pageNumber.toString());
|
||||||
params = params.append('pageIndex', shopParams.pageSize.toString());
|
params = params.append('pageIndex', this.shopParams.pageSize.toString());
|
||||||
|
|
||||||
return this.http.get<IPagination>(this.baseURL + 'products', {observe: 'response', params})
|
return this.http.get<IPagination>(this.baseURL + 'products', {observe: 'response', params})
|
||||||
.pipe(
|
.pipe(
|
||||||
map(response => {
|
map(response => {
|
||||||
return response.body;
|
this.productCache.set(Object.values(this.shopParams).join('-'), response.body.data);
|
||||||
|
this.pagination = response.body;
|
||||||
|
return this.pagination;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setShopParams(params: ShopParams){
|
||||||
|
this.shopParams = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
getShopParams(){
|
||||||
|
return this.shopParams;
|
||||||
|
}
|
||||||
|
|
||||||
getProduct(id: number){
|
getProduct(id: number){
|
||||||
|
let product: IProduct;
|
||||||
|
this.productCache.forEach((products: IProduct[]) => {
|
||||||
|
product = products.find(p => p.id === id);
|
||||||
|
})
|
||||||
|
|
||||||
|
if(product){
|
||||||
|
return of(product);
|
||||||
|
}
|
||||||
return this.http.get<IProduct>(this.baseURL + 'products/' + id);
|
return this.http.get<IProduct>(this.baseURL + 'products/' + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBrands(){
|
getBrands(){
|
||||||
return this.http.get<IBrand[]>(this.baseURL + 'products/brands');
|
if(this.brands.length > 0){
|
||||||
|
return of(this.brands);
|
||||||
|
}
|
||||||
|
return this.http.get<IBrand[]>(this.baseURL + 'products/brands').pipe(
|
||||||
|
map(response => {
|
||||||
|
this.brands = response;
|
||||||
|
return response;
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTypes(){
|
getTypes(){
|
||||||
return this.http.get<IType[]>(this.baseURL + 'products/types');
|
if(this.types.length > 0){
|
||||||
|
return of(this.types);
|
||||||
|
}
|
||||||
|
return this.http.get<IType[]>(this.baseURL + 'products/types').pipe(
|
||||||
|
map(response => {
|
||||||
|
this.types = response;
|
||||||
|
return response;
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>SkiNet</title>
|
<title>SkyNet</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
Loading…
Reference in New Issue
Block a user