diff --git a/Ombi/Ombi.Core/Engine/Interfaces/IRequestEngine.cs b/Ombi/Ombi.Core/Engine/Interfaces/IRequestEngine.cs index ace321444..c8391d9c1 100644 --- a/Ombi/Ombi.Core/Engine/Interfaces/IRequestEngine.cs +++ b/Ombi/Ombi.Core/Engine/Interfaces/IRequestEngine.cs @@ -11,5 +11,9 @@ namespace Ombi.Core.Engine Task RequestMovie(SearchMovieViewModel model); bool ShouldAutoApprove(RequestType requestType); Task> GetRequests(); + Task> GetRequests(int count, int position); + Task> SearchRequest(string search); + Task RemoveRequest(int requestId); + Task UpdateRequest(RequestViewModel request); } } \ No newline at end of file diff --git a/Ombi/Ombi.Core/Engine/RequestEngine.cs b/Ombi/Ombi.Core/Engine/RequestEngine.cs index f4f02e2f7..3cf325122 100644 --- a/Ombi/Ombi.Core/Engine/RequestEngine.cs +++ b/Ombi/Ombi.Core/Engine/RequestEngine.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading.Tasks; using Ombi.Core.Models.Requests; @@ -7,6 +8,7 @@ using Ombi.Core.Models.Search; using Ombi.Core.Requests.Models; using Ombi.Store.Entities; using Ombi.TheMovieDbApi; +using Ombi.Helpers; namespace Ombi.Core.Engine { @@ -233,7 +235,41 @@ namespace Ombi.Core.Engine public async Task> GetRequests() { var allRequests = await RequestService.GetAllAsync(); - var viewModel = allRequests.Select(movie => new RequestViewModel + var viewModel = MapToVm(allRequests); + return viewModel; + } + + public async Task> GetRequests(int count, int position) + { + var allRequests = await RequestService.GetAllAsync(count, position); + var viewModel = MapToVm(allRequests); + return viewModel; + } + public async Task> SearchRequest(string search) + { + var allRequests = await RequestService.GetAllAsync(); + var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase)); + var viewModel = MapToVm(results); + return viewModel; + } + public async Task UpdateRequest(RequestViewModel request) + { + var allRequests = await RequestService.GetAllAsync(); + var results = allRequests.FirstOrDefault(x => x.Id == request.Id); + + var model = RequestService.UpdateRequest(results); + return MapToVm(new List{model}).FirstOrDefault(); + } + + public async Task RemoveRequest(int requestId) + { + await RequestService.DeleteRequestAsync(requestId); + } + + + private IEnumerable MapToVm(IEnumerable model) + { + return model.Select(movie => new RequestViewModel { ProviderId = movie.ProviderId, Type = movie.Type, @@ -259,8 +295,6 @@ namespace Ombi.Core.Engine //RootFolders = rootFolders.ToArray(), //CurrentRootPath = radarr.Enabled ? GetRootPath(movie.RootFolderSelected, radarr).Result : null }).ToList(); - return viewModel; } - } } \ No newline at end of file diff --git a/Ombi/Ombi.Core/Models/Requests/IRequestService.cs b/Ombi/Ombi.Core/Models/Requests/IRequestService.cs index 1cc56dea8..deb40703f 100644 --- a/Ombi/Ombi.Core/Models/Requests/IRequestService.cs +++ b/Ombi/Ombi.Core/Models/Requests/IRequestService.cs @@ -16,11 +16,13 @@ namespace Ombi.Core.Requests.Models Task CheckRequestAsync(int providerId); Task CheckRequestAsync(string musicId); void DeleteRequest(RequestModel request); + Task DeleteRequestAsync(int request); Task DeleteRequestAsync(RequestModel request); RequestModel Get(int id); IEnumerable GetAll(); Task> GetAllAsync(); + Task> GetAllAsync(int count, int position); Task GetAsync(int id); - RequestBlobs UpdateRequest(RequestModel model); + RequestModel UpdateRequest(RequestModel model); } } \ No newline at end of file diff --git a/Ombi/Ombi.Core/Models/Requests/JsonRequestService.cs b/Ombi/Ombi.Core/Models/Requests/JsonRequestService.cs index f5418e74a..db741bac7 100644 --- a/Ombi/Ombi.Core/Models/Requests/JsonRequestService.cs +++ b/Ombi/Ombi.Core/Models/Requests/JsonRequestService.cs @@ -92,11 +92,19 @@ namespace Ombi.Core.Models.Requests var blob = await Repo.GetAsync(request.Id).ConfigureAwait(false); Repo.Delete(blob); } + public async Task DeleteRequestAsync(int request) + { + var blob = await Repo.GetAsync(request).ConfigureAwait(false); + Repo.Delete(blob); + } - public RequestBlobs UpdateRequest(RequestModel model) + public RequestModel UpdateRequest(RequestModel model) { - var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id }; - return Repo.Update(entity); + var b = Repo.Get(model.Id); + b.Content = ByteConverterHelper.ReturnBytes(model); + var blob = Repo.Update(b); + return model; + } public RequestModel Get(int id) @@ -159,6 +167,24 @@ namespace Ombi.Core.Models.Requests return retVal; } + public async Task> GetAllAsync(int count, int position) + { + var blobs = await Repo.GetAllAsync(count, position).ConfigureAwait(false); + var retVal = new List(); + + foreach (var b in blobs) + { + if (b == null) + { + continue; + } + var model = ByteConverterHelper.ReturnObject(b.Content); + model.Id = b.Id; + retVal.Add(model); + } + return retVal; + } + public void BatchUpdate(IEnumerable model) { var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList(); diff --git a/Ombi/Ombi.Helpers/StringHelper.cs b/Ombi/Ombi.Helpers/StringHelper.cs new file mode 100644 index 000000000..c936490f3 --- /dev/null +++ b/Ombi/Ombi.Helpers/StringHelper.cs @@ -0,0 +1,12 @@ +using System.Globalization; + +namespace Ombi.Helpers +{ + public static class StringHelper + { + public static bool Contains(this string paragraph, string word, CompareOptions opts) + { + return CultureInfo.CurrentUICulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0; + } + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Store/Repository/IRequestRepository.cs b/Ombi/Ombi.Store/Repository/IRequestRepository.cs index 4e1ac2798..a24985c34 100644 --- a/Ombi/Ombi.Store/Repository/IRequestRepository.cs +++ b/Ombi/Ombi.Store/Repository/IRequestRepository.cs @@ -11,6 +11,7 @@ namespace Ombi.Store.Repository RequestBlobs Get(int id); IEnumerable GetAll(); Task> GetAllAsync(); + Task> GetAllAsync(int count, int position); Task GetAsync(int id); RequestBlobs Insert(RequestBlobs entity); Task InsertAsync(RequestBlobs entity); diff --git a/Ombi/Ombi.Store/Repository/RequestJsonRepository.cs b/Ombi/Ombi.Store/Repository/RequestJsonRepository.cs index f16b96d51..ba0472bac 100644 --- a/Ombi/Ombi.Store/Repository/RequestJsonRepository.cs +++ b/Ombi/Ombi.Store/Repository/RequestJsonRepository.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; @@ -61,6 +62,18 @@ namespace Ombi.Store.Repository //}, 5); //return item; } + public async Task> GetAllAsync(int count, int position) + { + //var key = "GetAll"; + //var item = await Cache.GetOrSetAsync(key, async () => + //{ + + var page = await Db.Requests.ToListAsync().ConfigureAwait(false); + return page.Skip(position).Take(count); + + //}, 5); + //return item; + } public RequestBlobs Get(int id) { @@ -99,9 +112,17 @@ namespace Ombi.Store.Repository public RequestBlobs Update(RequestBlobs entity) { - - return Db.Requests.Update(entity).Entity; - Db.SaveChanges(); + try + { + Db.SaveChanges(); + + return entity; + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } } diff --git a/Ombi/Ombi/Controllers/BaseApiController.cs b/Ombi/Ombi/Controllers/BaseV1ApiController.cs similarity index 89% rename from Ombi/Ombi/Controllers/BaseApiController.cs rename to Ombi/Ombi/Controllers/BaseV1ApiController.cs index f122c578b..87d776ae6 100644 --- a/Ombi/Ombi/Controllers/BaseApiController.cs +++ b/Ombi/Ombi/Controllers/BaseV1ApiController.cs @@ -1,7 +1,7 @@ #region Copyright // /************************************************************************ // Copyright (c) 2017 Jamie Rees -// File: BaseApiController.cs +// File: BaseV1ApiController.cs // Created By: Jamie Rees // // Permission is hereby granted, free of charge, to any person obtaining @@ -29,8 +29,9 @@ using Microsoft.AspNetCore.Mvc; namespace Ombi.Controllers { - [Route("api/[controller]")] - public class BaseApiController : Controller + [Route(ApiBase)] + public class BaseV1ApiController : Controller { + protected const string ApiBase = "api/v1/[controller]"; } } \ No newline at end of file diff --git a/Ombi/Ombi/Controllers/RequestController.cs b/Ombi/Ombi/Controllers/RequestController.cs index 6fa16fca6..d90268845 100644 --- a/Ombi/Ombi/Controllers/RequestController.cs +++ b/Ombi/Ombi/Controllers/RequestController.cs @@ -7,7 +7,7 @@ using Ombi.Core.Models.Search; namespace Ombi.Controllers { - public class RequestController : BaseApiController + public class RequestController : BaseV1ApiController { public RequestController(IRequestEngine engine) { @@ -22,10 +22,34 @@ namespace Ombi.Controllers return await RequestEngine.GetRequests(); } + [HttpGet("{count:int}/{position:int}", Name = "GetRequestsByCount")] + public async Task> GetRequests(int count, int position) + { + return await RequestEngine.GetRequests(count, position); + } + [HttpPost("movie")] - public async Task SearchMovie([FromBody]SearchMovieViewModel movie) + public async Task RequestMovie([FromBody]SearchMovieViewModel movie) { return await RequestEngine.RequestMovie(movie); } + + [HttpGet("search/{searchTerm}")] + public async Task> Search(string searchTerm) + { + return await RequestEngine.SearchRequest(searchTerm); + } + + [HttpDelete("{requestId:int}")] + public async Task DeleteRequest(int requestId) + { + await RequestEngine.RemoveRequest(requestId); + } + + [HttpPost] + public async Task UpdateRequest([FromBody]RequestViewModel model) + { + return await RequestEngine.UpdateRequest(model); + } } } diff --git a/Ombi/Ombi/Controllers/SearchController.cs b/Ombi/Ombi/Controllers/SearchController.cs index 45200cbd1..3001791a4 100644 --- a/Ombi/Ombi/Controllers/SearchController.cs +++ b/Ombi/Ombi/Controllers/SearchController.cs @@ -8,7 +8,7 @@ using Ombi.Core.Models.Search; namespace Ombi.Controllers { - public class SearchController : BaseApiController + public class SearchController : BaseV1ApiController { public SearchController(IMovieEngine movie) { diff --git a/Ombi/Ombi/Startup.cs b/Ombi/Ombi/Startup.cs index bf16a1f69..f418fcc0e 100644 --- a/Ombi/Ombi/Startup.cs +++ b/Ombi/Ombi/Startup.cs @@ -41,7 +41,7 @@ namespace Ombi { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); - + if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); @@ -60,7 +60,7 @@ namespace Ombi }); app.UseMvc(routes => - { + { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); diff --git a/Ombi/Ombi/gulpfile.js b/Ombi/Ombi/gulpfile.js index 6b9624dde..1e5496d7c 100644 --- a/Ombi/Ombi/gulpfile.js +++ b/Ombi/Ombi/gulpfile.js @@ -31,7 +31,7 @@ var paths = { '@angular/platform-browser-dynamic', '@angular/http', '@angular/router', - '@angular/forms' + '@angular/forms', ], dest: './lib' }, @@ -56,7 +56,7 @@ var paths = { './bower_components/PACE/pace.js', './node_modules/bootstrap/dist/js/bootstrap.js', './node_modules/tether/dist/js/tether.js', - './systemjs.config.js' + './systemjs.config.js', ], dest: './lib/' }, @@ -118,7 +118,12 @@ var paths = { name: 'primeng', src: './node_modules/primeng/**/*.js', dest: './lib/primeng/' - } + }, + { + name: "angular2-infinite-scroll", + src: ['./node_modules/angular2-infinite-scroll/**/*.js', '!./node_modules/angular2-infinite-scroll/bundles/**/*.js'], + dest:"./lib/angular2-infinite-scroll/" + }, ], sass: { // Simple sass->css compilation src: ['./Styles/**/*.scss', '!./Styles/primeng/**'], diff --git a/Ombi/Ombi/package.json b/Ombi/Ombi/package.json index ad2eb6014..02951242e 100644 --- a/Ombi/Ombi/package.json +++ b/Ombi/Ombi/package.json @@ -16,10 +16,12 @@ "@angular/router": "^4.0.0", "@types/jquery": "^2.0.33", "@types/systemjs": "^0.20.2", + "angular2-infinite-scroll": "^0.3.4", + "bootstrap": "3.3.6", "core-js": "^2.4.1", "del": "^2.2.2", "gulp": "~3.9.1", - "gulp-changed": "^1.3.0", + "gulp-changed": "^1.3.0", "gulp-clean-css": "^3.0.4", "gulp-filter": "^5.0.0", "gulp-if": "^2.0.2", @@ -39,7 +41,6 @@ "systemjs-builder": "^0.15.34", "tether": "^1.4.0", "typescript": "^2.2.1", - "zone.js": "^0.8.5", - "bootstrap": "3.3.6" + "zone.js": "^0.8.5" } } diff --git a/Ombi/Ombi/wwwroot/app/app.module.ts b/Ombi/Ombi/wwwroot/app/app.module.ts index c7a1dee52..8c7d4584b 100644 --- a/Ombi/Ombi/wwwroot/app/app.module.ts +++ b/Ombi/Ombi/wwwroot/app/app.module.ts @@ -8,6 +8,8 @@ import { AppComponent } from './app.component'; import { RouterModule, Routes } from '@angular/router'; import { HttpModule } from '@angular/http'; +import { InfiniteScrollModule } from 'angular2-infinite-scroll/angular2-infinite-scroll' + import { SearchComponent } from './search/search.component'; import { RequestComponent } from './requests/request.component'; import { PageNotFoundComponent } from './errors/not-found.component'; @@ -41,7 +43,8 @@ const routes: Routes = [ FormsModule, SettingsModule, DataTableModule, - SharedModule + SharedModule, + InfiniteScrollModule ], declarations: [ AppComponent, diff --git a/Ombi/Ombi/wwwroot/app/interfaces/IRequestModel.ts b/Ombi/Ombi/wwwroot/app/interfaces/IRequestModel.ts index 31db39bf7..c93a171c1 100644 --- a/Ombi/Ombi/wwwroot/app/interfaces/IRequestModel.ts +++ b/Ombi/Ombi/wwwroot/app/interfaces/IRequestModel.ts @@ -24,4 +24,9 @@ export enum RequestType { movie = 1, tvShow = 2 +} + +export interface IRequestsPageScroll { + count: number, + position:number } \ No newline at end of file diff --git a/Ombi/Ombi/wwwroot/app/requests/request.component.html b/Ombi/Ombi/wwwroot/app/requests/request.component.html index b2654cbdc..f743e16d4 100644 --- a/Ombi/Ombi/wwwroot/app/requests/request.component.html +++ b/Ombi/Ombi/wwwroot/app/requests/request.component.html @@ -1,46 +1,182 @@ -

Requests

- - - - - - - - - - - - - - -
-
-
- - - -
-
-
-
-
Type:
-
{{request.type}}
-
-
-
Status:
-
{{request.status}}
-
-
-
Approved:
-
{{request.approved}}
-
-
-
Available:
-
{{request.available}}
-
-
-
-
-
-
-
+

Requests

+ +
+
+ +
+
+
+ +
+ + +
+ + +
+
+ + poster + poster + +
+ +
+ +
+
+ Status: + {{request.status}} +
+ +
+ Request status: + Request Available + Processing Request + Request Denied + + Pending Approval + +
+
+ Denied: + +
+ + +
Release Date: {{request.releaseDate}}
+ + + +
Requested By: {{request.requestedUsers}}
+ +
Requested Date: {{request.requestedDate}}
+ +
+ + + + + + + +
+
+
+ +
+ + + +
+ + + + + + + + + + + +
+ + +
+ + + +
+
+
+ + + + + + + + + + +
+ + + + + +
+
+
+ + + + +
+
diff --git a/Ombi/Ombi/wwwroot/app/requests/request.component.ts b/Ombi/Ombi/wwwroot/app/requests/request.component.ts index 65a733b77..3f7d96e51 100644 --- a/Ombi/Ombi/wwwroot/app/requests/request.component.ts +++ b/Ombi/Ombi/wwwroot/app/requests/request.component.ts @@ -1,4 +1,10 @@ import { Component, OnInit } from '@angular/core'; +import { Subject } from 'rxjs/Subject'; +import 'rxjs/add/operator/debounceTime'; +import 'rxjs/add/operator/distinctUntilChanged'; +import 'rxjs/add/operator/map'; + + import 'rxjs/add/operator/debounceTime'; import 'rxjs/add/operator/distinctUntilChanged'; import 'rxjs/add/operator/map'; @@ -14,11 +20,83 @@ import { IRequestModel } from '../interfaces/IRequestModel'; providers: [RequestService] }) export class RequestComponent implements OnInit { - constructor(private requestService: RequestService) { } + constructor(private requestService: RequestService) { + this.searchChanged + .debounceTime(600) // Wait Xms afterthe last event before emitting last event + .distinctUntilChanged() // only emit if value is different from previous value + .subscribe(x => { + this.searchText = x as string; + if (this.searchText === "") { + this.resetSearch(); + return; + } + this.requestService.searchRequests(this.searchText).subscribe(x => this.requests = x); + }); + } requests: IRequestModel[]; + searchChanged: Subject = new Subject(); + searchText: string; + + private currentlyLoaded: number; + private amountToLoad : number; + ngOnInit() { - this.requestService.getAllRequests().subscribe(x => this.requests = x); + this.amountToLoad = 5; + this.currentlyLoaded = 5; + this.loadInit(); + } + + loadMore() { + this.requestService.getRequests(this.amountToLoad, this.currentlyLoaded + 1).subscribe(x => { + this.requests.push.apply(this.requests, x); + this.currentlyLoaded = this.currentlyLoaded + this.amountToLoad; + }); + } + + search(text: any) { + this.searchChanged.next(text.target.value); + } + + removeRequest(request: IRequestModel) { + this.requestService.removeRequest(request).subscribe(); + this.removeRequestFromUi(request); + } + + changeAvailability(request: IRequestModel, available: boolean) { + request.available = available; + this.updateRequest(request); + } + + approve(request: IRequestModel) { + request.approved = true; + this.updateRequest(request); + } + + deny(request: IRequestModel) { + request.approved = false; + request.denied = true; + this.updateRequest(request); + } + + private updateRequest(request: IRequestModel) { + this.requestService.updateRequest(request).subscribe(x => request = x); + } + + private loadInit() { + this.requestService.getRequests(this.amountToLoad, 0).subscribe(x => this.requests = x); + } + + private resetSearch() { + this.currentlyLoaded = 5; + this.loadInit(); + } + + private removeRequestFromUi(key : IRequestModel) { + var index = this.requests.indexOf(key, 0); + if (index > -1) { + this.requests.splice(index, 1); + } } } \ No newline at end of file diff --git a/Ombi/Ombi/wwwroot/app/services/request.service.ts b/Ombi/Ombi/wwwroot/app/services/request.service.ts index fe8d188f0..adcdd8667 100644 --- a/Ombi/Ombi/wwwroot/app/services/request.service.ts +++ b/Ombi/Ombi/wwwroot/app/services/request.service.ts @@ -8,16 +8,32 @@ import { ISearchMovieResult } from '../interfaces/ISearchMovieResult'; import { IRequestModel } from '../interfaces/IRequestModel'; @Injectable() -export class RequestService { - constructor(private http: Http) { +export class RequestService extends ServiceHelpers { + constructor(http: Http) { + super(http, '/api/v1/Request/'); } requestMovie(movie: ISearchMovieResult): Observable { - return this.http.post('/api/Request/Movie/', JSON.stringify(movie), ServiceHelpers.RequestOptions).map(ServiceHelpers.extractData); + return this.http.post(`${this.url}/Movie/`, JSON.stringify(movie), { headers: this.headers }).map(this.extractData); } getAllRequests(): Observable { - return this.http.get('/api/request').map(ServiceHelpers.extractData); + return this.http.get(this.url).map(this.extractData); } + getRequests(count: number, position: number): Observable { + return this.http.get(`${this.url}/${count}/${position}`).map(this.extractData); + } + + searchRequests(search: string): Observable { + return this.http.get(`${this.url}/search/${search}`).map(this.extractData); + } + + removeRequest(request: IRequestModel): Observable { + return this.http.delete(`${this.url}/${request.id}`).map(this.extractData); + } + + updateRequest(request: IRequestModel) : Observable { + return this.http.post(`${this.url}/`, JSON.stringify(request), { headers: this.headers }).map(this.extractData); + } } \ No newline at end of file diff --git a/Ombi/Ombi/wwwroot/app/services/search.service.ts b/Ombi/Ombi/wwwroot/app/services/search.service.ts index f684fa235..a9de2ddfe 100644 --- a/Ombi/Ombi/wwwroot/app/services/search.service.ts +++ b/Ombi/Ombi/wwwroot/app/services/search.service.ts @@ -6,24 +6,25 @@ import { ServiceHelpers } from './service.helpers'; import { ISearchMovieResult } from '../interfaces/ISearchMovieResult'; @Injectable() -export class SearchService { - constructor(private http: Http) { +export class SearchService extends ServiceHelpers { + constructor(http: Http) { + super(http, "/api/v1/search"); } searchMovie(searchTerm: string): Observable { - return this.http.get('/api/Search/Movie/' + searchTerm).map(ServiceHelpers.extractData); + return this.http.get(`${this.url}/Movie/` + searchTerm).map(this.extractData); } popularMovies(): Observable { - return this.http.get('/api/Search/Movie/Popular').map(ServiceHelpers.extractData); + return this.http.get(`${this.url}/Movie/Popular`).map(this.extractData); } upcomignMovies(): Observable { - return this.http.get('/api/Search/Movie/upcoming').map(ServiceHelpers.extractData); + return this.http.get(`${this.url}/Movie/upcoming`).map(this.extractData); } nowPlayingMovies(): Observable { - return this.http.get('/api/Search/Movie/nowplaying').map(ServiceHelpers.extractData); + return this.http.get(`${this.url}/Movie/nowplaying`).map(this.extractData); } topRatedMovies(): Observable { - return this.http.get('/api/Search/Movie/toprated').map(ServiceHelpers.extractData); + return this.http.get(`${this.url}/Movie/toprated`).map(this.extractData); } } \ No newline at end of file diff --git a/Ombi/Ombi/wwwroot/app/services/service.helpers.ts b/Ombi/Ombi/wwwroot/app/services/service.helpers.ts index b8b0176a6..f1d111c49 100644 --- a/Ombi/Ombi/wwwroot/app/services/service.helpers.ts +++ b/Ombi/Ombi/wwwroot/app/services/service.helpers.ts @@ -1,15 +1,29 @@ -import { Headers, RequestOptions, Response } from '@angular/http'; +import { Headers, Response, Http } from '@angular/http'; +import { Observable } from 'rxjs/Observable'; export class ServiceHelpers { - public static Headers = new Headers({ 'Content-Type': 'application/json' }); - public static RequestOptions = new RequestOptions({ - headers: ServiceHelpers.Headers - }); + constructor(protected http: Http, protected url: string) { + this.headers = new Headers(); + this.headers.append('Content-Type', 'application/json; charset=utf-8'); + } + + protected headers: Headers; - public static extractData(res: Response) { - console.log(res); - return res.json(); + protected extractData(res: Response) { + let body = res.json(); + //console.log('extractData', body || {}); + return body || {}; } + protected handleError(error: any) { + // In a real world app, we might use a remote logging infrastructure + // We'd also dig deeper into the error to get a better message + let errMsg = (error.message) ? error.message : + error.status ? `${error.status} - ${error.statusText}` : 'Server error'; + console.error(errMsg); // log to console instead + return Observable.throw(errMsg); + } + + } \ No newline at end of file