From 7c04274b5ad8f2818d39910ff790aed7db9c349c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Ca=C3=B1izares=20Est=C3=A9vez?= Date: Thu, 17 Nov 2016 18:29:47 +0100 Subject: [PATCH] service in spa to retrieve data from catalog api, project structure simplified --- .../Client/modules/app.component.ts | 12 +- .../modules/catalog/catalog.component.ts | 27 ++- .../Client/modules/catalog/catalog.module.ts | 10 +- .../Client/modules/catalog/catalog.service.ts | 15 ++ .../shared/layout/footer.component.html | 2 +- .../modules/shared/models/catalog.model.ts | 6 + .../shared/models/catalogItem.model.ts | 3 + .../modules/shared/models/user.model.spec.ts | 13 -- .../shared/services/api-gateway.service.ts | 207 ------------------ .../api-translation-loader.service.ts | 23 -- .../shared/services/content.service.ts | 13 -- .../modules/shared/services/data.service.ts | 36 ++- .../services/http-error-handler.service.ts | 25 --- .../Client/modules/shared/shared.module.ts | 12 +- .../config/webpack.config.js | 2 +- .../eShopOnContainers.WebSPA/package.json | 3 +- 16 files changed, 90 insertions(+), 319 deletions(-) create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.service.ts create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalog.model.ts create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalogItem.model.ts delete mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/user.model.spec.ts delete mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/api-gateway.service.ts delete mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/api-translation-loader.service.ts delete mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/content.service.ts delete mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/http-error-handler.service.ts diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.component.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.component.ts index fcd39952e..b32e8929b 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.component.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.component.ts @@ -1,7 +1,6 @@ import { Title } from '@angular/platform-browser'; import { Component, ViewEncapsulation, OnInit } from '@angular/core'; import { RouterModule } from '@angular/router'; -import { TranslateService } from 'ng2-translate/ng2-translate'; import { DataService } from './shared/services/data.service'; @@ -18,20 +17,15 @@ import { DataService } from './shared/services/data.service'; export class AppComponent implements OnInit { - constructor(private translate: TranslateService, private titleService: Title) { - // this language will be used as a fallback when a translation isn't found in the current language - translate.setDefaultLang('en'); + constructor(private titleService: Title) { - // the lang to use, if the lang isn't available, it will use the current loader to get them - translate.use('en'); } ngOnInit() { - this.translate.get('title') - .subscribe(title => this.setTitle(title)); + } public setTitle(newTitle: string) { - this.titleService.setTitle(newTitle); + this.titleService.setTitle('eShopOnContainers'); } } diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.component.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.component.ts index 53ca23abe..a3772900c 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.component.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.component.ts @@ -1,15 +1,28 @@ import { Component, OnInit } from '@angular/core'; +import { CatalogService } from './catalog.service'; +import { Catalog } from '../shared/models/catalog.model'; +import { CatalogItem } from '../shared/models/catalogItem.model'; @Component({ - selector: 'appc-catalog', - styleUrls: ['./catalog.component.scss'], - templateUrl: './catalog.component.html' + selector: 'appc-catalog', + styleUrls: ['./catalog.component.scss'], + templateUrl: './catalog.component.html' }) export class CatalogComponent implements OnInit { - constructor() { } + private brands: any[]; + private types: any[]; + private items: CatalogItem[]; + private filteredItems: any[]; + private catalog: Catalog; - ngOnInit() { - console.log('catalog component loaded'); - } + constructor(private service: CatalogService) { } + ngOnInit() { + console.log('catalog component loaded'); + this.service.getCatalog().subscribe((catalog: Catalog) => { + this.catalog = catalog; + this.items = catalog.data; + console.log(this.items.length + ' catalog items retrieved from api'); + }); + } } diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.module.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.module.ts index 95e541939..4ecc504b7 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.module.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.module.ts @@ -1,11 +1,13 @@ -import { NgModule } from '@angular/core'; +import { NgModule } from '@angular/core'; -import { CatalogComponent } from './catalog.component'; -import { routing } from './catalog.routes'; +import { CatalogComponent } from './catalog.component'; +import { routing } from './catalog.routes'; +import { CatalogService } from './catalog.service'; @NgModule({ imports: [routing], - declarations: [CatalogComponent] + declarations: [CatalogComponent], + providers: [CatalogService] }) export class CatalogModule { } diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.service.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.service.ts new file mode 100644 index 000000000..8932531da --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.service.ts @@ -0,0 +1,15 @@ +import { Injectable } from '@angular/core'; + +import { DataService } from '../shared/services/data.service'; + +@Injectable() +export class CatalogService { + private catalogUrl: string = 'http://eshopcontainers:5101/api/v1/catalog/items'; + + constructor(private service: DataService) { + } + + getCatalog(){ + return this.service.get(this.catalogUrl); + } +} \ No newline at end of file diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/layout/footer.component.html b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/layout/footer.component.html index 977840161..11a669057 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/layout/footer.component.html +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/layout/footer.component.html @@ -2,7 +2,7 @@

- © 2015-2016 {{'title' | translate}} Company + © 2015-2016 {{'title'}} Company

diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalog.model.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalog.model.ts new file mode 100644 index 000000000..7fe3dec15 --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalog.model.ts @@ -0,0 +1,6 @@ +import {CatalogItem} from './catalogItem.model'; + +export class Catalog { + constructor(public pageIndex: number, public data: CatalogItem[], public pageSize: number, public count: number) { + } +} diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalogItem.model.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalogItem.model.ts new file mode 100644 index 000000000..c89193e20 --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalogItem.model.ts @@ -0,0 +1,3 @@ +export class CatalogItem { + constructor(public Id: string, public Name: string, public Description: string, public Price: number, public PictureUri: string, public CatalogBrandId: number, public CatalogBrand: string, public CatalogTypeId: number, public CatalogType: string) { } +} diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/user.model.spec.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/user.model.spec.ts deleted file mode 100644 index b38cd5490..000000000 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/user.model.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { User } from './user.model'; -// todo: I dont think user follows angular style guides - -describe('User Model', () => { - it('has displayName', () => { - let userModel: User = {displayName: 'test', roles: ['1']}; - expect(userModel.displayName).toEqual('test'); - }); - it('has displayName', () => { - let userModel: User = {displayName: 'test', roles: ['admin']}; - expect(userModel.roles[0]).toEqual('admin'); - }); -}); diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/api-gateway.service.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/api-gateway.service.ts deleted file mode 100644 index 6df54875e..000000000 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/api-gateway.service.ts +++ /dev/null @@ -1,207 +0,0 @@ -// CREDIT: -// The vast majority of this code came right from Ben Nadel's post: -// http://www.bennadel.com/blog/3047-creating-specialized-http-clients-in-angular-2-beta-8.htm -// -// My updates are mostly adapting it for Typescript: -// 1. Importing required modules -// 2. Adding type notations -// 3. Using the 'fat-arrow' syntax to properly scope in-line functions -// -import 'rxjs/add/operator/map'; -import 'rxjs/add/operator/catch'; -import 'rxjs/add/operator/finally'; - -import { Injectable } from '@angular/core'; -import { Http, Response, RequestOptions, RequestMethod, URLSearchParams } from '@angular/http'; -import { Observable } from 'rxjs/Observable'; -import { Subject } from 'rxjs/Subject'; - -import { HttpErrorHandlerService } from './http-error-handler.service'; - -// Import the rxjs operators we need (in a production app you'll -// probably want to import only the operators you actually use) -// -export class ApiGatewayOptions { - method: RequestMethod; - url: string; - headers: any = {}; - params = {}; - data = {}; -} - - -@Injectable() -export class ApiGatewayService { - - // Define the internal Subject we'll use to push the command count - private pendingCommandsSubject = new Subject(); - private pendingCommandCount = 0; - - // Provide the *public* Observable that clients can subscribe to - private pendingCommands$: Observable; - - constructor(private http: Http, private httpErrorHandler: HttpErrorHandlerService) { - this.pendingCommands$ = this.pendingCommandsSubject.asObservable(); - } - - // I perform a GET request to the API, appending the given params - // as URL search parameters. Returns a stream. - get(url: string, params: any): Observable { - let options = new ApiGatewayOptions(); - options.method = RequestMethod.Get; - options.url = url; - options.params = params; - return this.request(options); - } - - // I perform a POST request to the API. If both the params and data - // are present, the params will be appended as URL search parameters - // and the data will be serialized as a JSON payload. If only the - // data is present, it will be serialized as a JSON payload. Returns - // a stream. - post(url: string, data: any, params: any): Observable { - if (!data) { - data = params; - params = {}; - } - let options = new ApiGatewayOptions(); - options.method = RequestMethod.Post; - options.url = url; - options.params = params; - options.data = data; - return this.request(options); - } - - - private request(options: ApiGatewayOptions): Observable { - options.method = (options.method || RequestMethod.Get); - options.url = (options.url || ''); - options.headers = (options.headers || {}); - options.params = (options.params || {}); - options.data = (options.data || {}); - - this.interpolateUrl(options); - this.addXsrfToken(options); - this.addContentType(options); - // TODO add auth token when available - // this.addAuthToken(options); - - let requestOptions = new RequestOptions(); - requestOptions.method = options.method; - requestOptions.url = options.url; - requestOptions.headers = options.headers; - requestOptions.search = this.buildUrlSearchParams(options.params); - requestOptions.body = JSON.stringify(options.data); - - let isCommand = (options.method !== RequestMethod.Get); - - if (isCommand) { - this.pendingCommandsSubject.next(++this.pendingCommandCount); - } - - let stream = this.http.request(options.url, requestOptions) - .catch((error: any) => { - this.httpErrorHandler.handle(error); - return Observable.throw(error); - }) - .map(this.unwrapHttpValue) - .catch((error: any) => { - return Observable.throw(this.unwrapHttpError(error)); - }) - .finally(() => { - if (isCommand) { - this.pendingCommandsSubject.next(--this.pendingCommandCount); - } - }); - - return stream; - } - - - private addContentType(options: ApiGatewayOptions): ApiGatewayOptions { - if (options.method !== RequestMethod.Get) { - options.headers['Content-Type'] = 'application/json; charset=UTF-8'; - } - return options; - } - - private addAuthToken(options: ApiGatewayOptions): ApiGatewayOptions { - options.headers.Authorization = 'Bearer ' + JSON.parse(sessionStorage.getItem('accessToken')); - return options; - } - - private extractValue(collection: any, key: string): any { - let value = collection[key]; - delete (collection[key]); - return value; - } - - private addXsrfToken(options: ApiGatewayOptions): ApiGatewayOptions { - let xsrfToken = this.getXsrfCookie(); - if (xsrfToken) { - options.headers['X-XSRF-TOKEN'] = xsrfToken; - } - return options; - } - - private getXsrfCookie(): string { - let matches = document.cookie.match(/\bXSRF-TOKEN=([^\s;]+)/); - try { - return (matches && decodeURIComponent(matches[1])); - } catch (decodeError) { - return (''); - } - } - - private addCors(options: ApiGatewayOptions): ApiGatewayOptions { - options.headers['Access-Control-Allow-Origin'] = '*'; - return options; - } - - private buildUrlSearchParams(params: any): URLSearchParams { - let searchParams = new URLSearchParams(); - for (let key in params) { - if (params.hasOwnProperty(key)) { - searchParams.append(key, params[key]); - } - } - return searchParams; - } - - private interpolateUrl(options: ApiGatewayOptions): ApiGatewayOptions { - options.url = options.url.replace(/:([a-zA-Z]+[\w-]*)/g, ($0, token) => { - // Try to move matching token from the params collection. - if (options.params.hasOwnProperty(token)) { - return (this.extractValue(options.params, token)); - } - // Try to move matching token from the data collection. - if (options.data.hasOwnProperty(token)) { - return (this.extractValue(options.data, token)); - } - // If a matching value couldn't be found, just replace - // the token with the empty string. - return (''); - }); - // Clean up any repeating slashes. - options.url = options.url.replace(/\/{2,}/g, '/'); - // Clean up any trailing slashes. - options.url = options.url.replace(/\/+$/g, ''); - - return options; - } - - private unwrapHttpError(error: any): any { - try { - return (error.json()); - } catch (jsonError) { - return ({ - code: -1, - message: 'An unexpected error occurred.' - }); - } - } - - private unwrapHttpValue(value: Response): any { - return (value.json()); - } -} diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/api-translation-loader.service.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/api-translation-loader.service.ts deleted file mode 100644 index 2105706b9..000000000 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/api-translation-loader.service.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; -import { TranslateLoader } from 'ng2-translate/ng2-translate'; -import { MissingTranslationHandler, MissingTranslationHandlerParams } from 'ng2-translate/ng2-translate'; - -import { ContentService } from './content.service'; - -@Injectable() -export class ApiTranslationLoader implements TranslateLoader { - - constructor(private cs: ContentService) { } - - getTranslation(lang: string): Observable { - return this.cs.get(lang); - } -} - -@Injectable() -export class CustomMissingTranslationHandler implements MissingTranslationHandler { - handle(params: MissingTranslationHandlerParams) { - return params.key; - } -} diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/content.service.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/content.service.ts deleted file mode 100644 index 8f67ec197..000000000 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/content.service.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Injectable } from '@angular/core'; - -import { DataService } from './data.service'; - -@Injectable() -export class ContentService { - - constructor(public dataService: DataService) { } - - get(lang?: string): any { - return this.dataService.get('api/content?lang=' + (lang ? lang : 'en')); - } -} diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/data.service.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/data.service.ts index 1b08aeada..8fca8fe26 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/data.service.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/data.service.ts @@ -1,17 +1,47 @@ import { Injectable } from '@angular/core'; +import { Http, Response, RequestOptionsArgs, RequestMethod, Headers } from '@angular/http'; -import { ApiGatewayService } from './api-gateway.service'; +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/throw'; +import { Observer } from 'rxjs/Observer'; +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/catch'; @Injectable() export class DataService { - constructor(public http: ApiGatewayService) { } + constructor(public http: Http) { } get(url: string, params?: any) { - return this.http.get(url, undefined); + let options: RequestOptionsArgs = {}; + options.headers = new Headers(); + this.addCors(options); + + return this.http.get(url, options).map(((res: Response) => { + return res.json(); + })).catch(this.handleError); } post(url: string, data: any, params?: any) { return this.http.post(url, data, params); } + + private addCors(options: RequestOptionsArgs): RequestOptionsArgs { + options.headers.append('Access-Control-Allow-Origin', '*'); + return options; + } + + private handleError(error: any) { + console.error('server error:', error); + if (error instanceof Response) { + let errMessage = ''; + try { + errMessage = error.json().error; + } catch (err) { + errMessage = error.statusText; + } + return Observable.throw(errMessage); + } + return Observable.throw(error || 'Node.js server error'); + } } diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/http-error-handler.service.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/http-error-handler.service.ts deleted file mode 100644 index 23f4825f1..000000000 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/http-error-handler.service.ts +++ /dev/null @@ -1,25 +0,0 @@ -// CREDIT: -// The vast majority of this code came right from Ben Nadel's post: -// http://www.bennadel.com/blog/3047-creating-specialized-http-clients-in-angular-2-beta-8.htm -// -// My updates are mostly adapting it for Typescript: -// 1. Importing required modules -// 2. Adding type notations -// 3. Using the 'fat-arrow' syntax to properly scope in-line functions -// -import { Injectable } from '@angular/core'; -import { Router } from '@angular/router'; - -@Injectable() -export class HttpErrorHandlerService { - - constructor(private _router: Router) { } - - handle(error: any) { - if (error.status === 401) { - sessionStorage.clear(); - // window.location.href = 'login'; - this._router.navigate(['Login']); - } - } -} diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/shared.module.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/shared.module.ts index b4e717f36..67b80ed8a 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/shared.module.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/shared.module.ts @@ -4,7 +4,6 @@ import { FormsModule, ReactiveFormsModule, FormBuilder } from '@angular/forms'; import { RouterModule } from '@angular/router'; import { HttpModule, JsonpModule } from '@angular/http'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; -import { TranslateModule, TranslateLoader } from 'ng2-translate/ng2-translate'; import { PageHeadingComponent } from './directives/page-heading.directive'; import { DynamicFormComponent } from './forms/dynamic-form.component'; @@ -17,11 +16,7 @@ import { HeaderComponent } from './layout/header.component'; import { FooterComponent } from './layout/footer.component'; // Services import { DataService } from './services/data.service'; -import { ApiGatewayService } from './services/api-gateway.service'; import { AuthService } from './services/auth.service'; -import { HttpErrorHandlerService } from './services/http-error-handler.service'; -import { ApiTranslationLoader } from './services/api-translation-loader.service'; -import { ContentService } from './services/content.service'; import { UtilityService } from './services/utility.service'; import { UppercasePipe } from './pipes/uppercase.pipe'; @@ -34,8 +29,7 @@ import { UppercasePipe } from './pipes/uppercase.pipe'; NgbModule.forRoot(), // No need to export as these modules don't expose any components/directive etc' HttpModule, - JsonpModule, - TranslateModule.forRoot({ provide: TranslateLoader, useClass: ApiTranslationLoader }) + JsonpModule ], declarations: [ DynamicFormComponent, @@ -54,7 +48,6 @@ import { UppercasePipe } from './pipes/uppercase.pipe'; ReactiveFormsModule, RouterModule, NgbModule, - TranslateModule, // Providers, Components, directive, pipes DynamicFormComponent, DynamicFormControlComponent, @@ -73,11 +66,8 @@ export class SharedModule { ngModule: SharedModule, providers: [ // Providers - HttpErrorHandlerService, - ApiGatewayService, AuthService, DataService, - ContentService, FormControlService, UtilityService ] diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/config/webpack.config.js b/src/Web/WebSPA/eShopOnContainers.WebSPA/config/webpack.config.js index 780f9955f..77e8afc07 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/config/webpack.config.js +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/config/webpack.config.js @@ -6,7 +6,7 @@ var extractCSS = new ExtractTextPlugin('styles.css'); var ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin; var devConfig = require('./webpack.config.dev'); var prodConfig = require('./webpack.config.prod'); -var isDevelopment = process.env.ASPNETCORE_ENVIRONMENT === 'Production'; +var isDevelopment = process.env.ASPNETCORE_ENVIRONMENT === 'Development'; console.log("==========Dev Mode = " + isDevelopment + " ============" ) diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/package.json b/src/Web/WebSPA/eShopOnContainers.WebSPA/package.json index 84c93350d..066f39baa 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/package.json +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/package.json @@ -35,7 +35,7 @@ "build:prod": "npm run setprod && npm run clean:dist && npm run build:vendor && npm run build:main", "lint": "npm run tslint \"Client/**/*.ts\"", "docs": "npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./Client/", - "version": "npm run build", + "version": "npm run build" }, "dependencies": { "@angular/common": "2.1.2", @@ -55,7 +55,6 @@ "core-js": "2.4.1", "font-awesome": "4.6.3", "isomorphic-fetch": "2.2.1", - "ng2-translate": "4.0.0", "normalize.css": "5.0.0", "preboot": "4.5.2", "rxjs": "5.0.0-beta.12",