Skip to content

Commit 73aff9d

Browse files
author
vakrilov
committed
feat(http): Support for HttpClinet with "nativescript-angular/http-client" module.
1 parent 6c4c278 commit 73aff9d

File tree

11 files changed

+353
-92
lines changed

11 files changed

+353
-92
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { NgModule, Optional, Inject, Injectable } from "@angular/core";
2+
3+
// IMPORTant: Importing "@angular/common/http" for the first time overwrites the
4+
// global.__extends function.
5+
const cachedExtends = global.__extends;
6+
import { HttpClientModule, HttpBackend } from "@angular/common/http";
7+
global.__extends = cachedExtends;
8+
9+
import { NSFileSystem } from "../file-system/ns-file-system";
10+
import { NsHttpBackEnd } from "./ns-http-backend";
11+
12+
@NgModule({
13+
providers: [
14+
NSFileSystem,
15+
NsHttpBackEnd,
16+
{ provide: HttpBackend, useExisting: NsHttpBackEnd },
17+
],
18+
imports: [
19+
HttpClientModule,
20+
],
21+
exports: [
22+
HttpClientModule,
23+
]
24+
})
25+
export class NativeScriptHttpClientModule {
26+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./http-client.module";
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { Injectable } from "@angular/core";
2+
import {
3+
HttpHandler, HttpRequest,
4+
HttpEvent, HttpEventType,
5+
XhrFactory, HttpResponse,
6+
HttpErrorResponse, HttpXhrBackend
7+
} from "@angular/common/http";
8+
import { Observable } from "rxjs/Observable";
9+
import { Observer } from "rxjs/Observer";
10+
11+
import { NSFileSystem } from "../file-system/ns-file-system";
12+
import { path } from "tns-core-modules/file-system";
13+
14+
@Injectable()
15+
export class NsHttpBackEnd extends HttpXhrBackend {
16+
constructor(xhrFactory: XhrFactory, private nsFileSystem: NSFileSystem) {
17+
super(xhrFactory);
18+
}
19+
20+
handle(req: HttpRequest<any>): Observable<HttpEvent<any>> {
21+
let result: Observable<HttpEvent<any>>;
22+
23+
if (isLocalRequest(req.url)) {
24+
result = this.handleLocalRequest(req.url);
25+
} else {
26+
result = super.handle(req);
27+
}
28+
29+
return result;
30+
}
31+
32+
private getAbsolutePath(url: string): string {
33+
url = url.replace("~", "").replace("/", "");
34+
url = path.join(this.nsFileSystem.currentApp().path, url);
35+
return url;
36+
}
37+
38+
private handleLocalRequest(url: string): Observable<HttpEvent<any>> {
39+
url = this.getAbsolutePath(url);
40+
41+
// request from local app resources
42+
return new Observable((observer: Observer<HttpEvent<any>>) => {
43+
if (this.nsFileSystem.fileExists(url)) {
44+
const localFile = this.nsFileSystem.fileFromPath(url);
45+
localFile.readText()
46+
.then((data) => {
47+
try {
48+
const json = JSON.parse(data);
49+
observer.next(createSuccessResponse(url, json, 200));
50+
observer.complete();
51+
} catch (error) {
52+
// Even though the response status was 2xx, this is still an error.
53+
// The parse error contains the text of the body that failed to parse.
54+
const errorResult = { error, text: data };
55+
observer.error(createErrorResponse(url, errorResult, 200));
56+
}
57+
}, (err: Object) => {
58+
observer.error(createErrorResponse(url, err, 400));
59+
60+
});
61+
} else {
62+
observer.error(createErrorResponse(url, "Not Found", 404));
63+
}
64+
});
65+
}
66+
}
67+
68+
function isLocalRequest(url: string): boolean {
69+
return url.indexOf("~") === 0 || url.indexOf("/") === 0;
70+
}
71+
72+
function createSuccessResponse(url: string, body: any, status: number): HttpEvent<any> {
73+
return new HttpResponse({
74+
url,
75+
body,
76+
status,
77+
statusText: "OK"
78+
});
79+
}
80+
81+
function createErrorResponse(url: string, body: any, status: number): HttpErrorResponse {
82+
return new HttpErrorResponse({
83+
url,
84+
error: body,
85+
status,
86+
statusText: "ERROR"
87+
});
88+
}

nativescript-angular/http.ts

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { NgModule } from "@angular/core";
2+
import { Http, XHRBackend, RequestOptions, HttpModule, XSRFStrategy } from "@angular/http";
3+
4+
import { NSXSRFStrategy, NSHttp } from "./ns-http";
5+
import { NSFileSystem } from "../file-system/ns-file-system";
6+
7+
export { NSHttp } from "./ns-http";
8+
9+
export function nsHttpFactory(backend, options, nsFileSystem) {
10+
return new NSHttp(backend, options, nsFileSystem);
11+
}
12+
13+
export function nsXSRFStrategyFactory() {
14+
return new NSXSRFStrategy();
15+
}
16+
17+
@NgModule({
18+
providers: [
19+
{ provide: XSRFStrategy, useFactory: nsXSRFStrategyFactory },
20+
NSFileSystem,
21+
{
22+
provide: Http, useFactory: nsHttpFactory,
23+
deps: [XHRBackend, RequestOptions, NSFileSystem]
24+
}
25+
],
26+
imports: [
27+
HttpModule,
28+
],
29+
exports: [
30+
HttpModule,
31+
]
32+
})
33+
export class NativeScriptHttpModule {
34+
}

nativescript-angular/http/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./http.module";

nativescript-angular/http/ns-http.ts

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -14,78 +14,78 @@ import "rxjs/add/observable/fromPromise";
1414
import { NSFileSystem } from "../file-system/ns-file-system";
1515

1616
export class NSXSRFStrategy {
17-
public configureRequest(_req: any) {
18-
// noop
19-
}
17+
public configureRequest(_req: any) {
18+
// noop
19+
}
2020
}
2121

2222
@Injectable()
2323
export class NSHttp extends Http {
24-
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private nsFileSystem: NSFileSystem) {
25-
super(backend, defaultOptions);
26-
}
24+
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private nsFileSystem: NSFileSystem) {
25+
super(backend, defaultOptions);
26+
}
2727

28-
/**
29-
* Performs a request with `request` http method.
30-
*/
31-
request(req: string | Request, options?: RequestOptionsArgs): Observable<Response> {
32-
const urlString = typeof req === "string" ? req : req.url;
33-
if (isLocalRequest(urlString)) {
34-
return this._requestLocalUrl(urlString);
35-
} else {
36-
return super.request(req, options);
28+
/**
29+
* Performs a request with `request` http method.
30+
*/
31+
request(req: string | Request, options?: RequestOptionsArgs): Observable<Response> {
32+
const urlString = typeof req === "string" ? req : req.url;
33+
if (isLocalRequest(urlString)) {
34+
return this._requestLocalUrl(urlString);
35+
} else {
36+
return super.request(req, options);
37+
}
3738
}
38-
}
3939

40-
/**
41-
* Performs a request with `get` http method.
42-
*/
43-
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
44-
if (isLocalRequest(url)) {
45-
return this._requestLocalUrl(url);
46-
} else {
47-
return super.get(url, options);
40+
/**
41+
* Performs a request with `get` http method.
42+
*/
43+
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
44+
if (isLocalRequest(url)) {
45+
return this._requestLocalUrl(url);
46+
} else {
47+
return super.get(url, options);
48+
}
4849
}
49-
}
5050

51-
/**
52-
* Uses a local file if `~/` resource is requested.
53-
* @param url
54-
*/
55-
private _requestLocalUrl(url: string): Observable<Response> {
56-
// normalize url
57-
url = normalizeLocalUrl(url);
58-
// request from local app resources
59-
return Observable.fromPromise<Response>(new Promise((resolve, reject) => {
60-
let app = this.nsFileSystem.currentApp();
61-
let localFile = app.getFile(url);
62-
if (localFile) {
63-
localFile.readText().then((data) => {
64-
resolve(responseOptions(data, 200, url));
65-
}, (err: Object) => {
66-
reject(responseOptions(err, 400, url));
67-
});
68-
} else {
69-
reject(responseOptions("Not Found", 404, url));
70-
}
71-
}));
72-
}
51+
/**
52+
* Uses a local file if `~/` resource is requested.
53+
* @param url
54+
*/
55+
private _requestLocalUrl(url: string): Observable<Response> {
56+
url = normalizeLocalUrl(url);
57+
58+
// request from local app resources
59+
return Observable.fromPromise<Response>(new Promise((resolve, reject) => {
60+
let app = this.nsFileSystem.currentApp();
61+
let localFile = app.getFile(url);
62+
if (localFile) {
63+
localFile.readText().then((data) => {
64+
resolve(responseOptions(data, 200, url));
65+
}, (err: Object) => {
66+
reject(responseOptions(err, 400, url));
67+
});
68+
} else {
69+
reject(responseOptions("Not Found", 404, url));
70+
}
71+
}));
72+
}
7373
}
7474

7575
function isLocalRequest(url: string): boolean {
76-
return url.indexOf("~") === 0 || url.indexOf("/") === 0;
76+
return url.indexOf("~") === 0 || url.indexOf("/") === 0;
7777
}
7878

7979
function normalizeLocalUrl(url: string): string {
80-
return url.replace("~", "").replace("/", "");
80+
return url.replace("~", "").replace("/", "");
8181
}
8282

8383
function responseOptions(body: string | Object, status: number, url: string): Response {
84-
return new Response(new ResponseOptions({
85-
body: body,
86-
status: status,
87-
statusText: "OK",
88-
type: status === 200 ? ResponseType.Default : ResponseType.Error,
89-
url: url
90-
}));
84+
return new Response(new ResponseOptions({
85+
body: body,
86+
status: status,
87+
statusText: "OK",
88+
type: status === 200 ? ResponseType.Default : ResponseType.Error,
89+
url: url
90+
}));
9191
}

nativescript-angular/platform-common.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
Sanitizer,
2121
InjectionToken
2222
} from "@angular/core";
23+
import { DOCUMENT } from "@angular/common";
2324

2425
import { rendererLog, rendererError } from "./trace";
2526
import {
@@ -56,9 +57,16 @@ export class NativeScriptSanitizer extends Sanitizer {
5657
}
5758
}
5859

60+
export class NativeScriptDocument {
61+
createElement(tag: string) {
62+
throw new Error("NativeScriptDocument is not DOM Document. There is no createElement() method.");
63+
}
64+
}
65+
5966
export const COMMON_PROVIDERS = [
6067
defaultPageFactoryProvider,
6168
{ provide: Sanitizer, useClass: NativeScriptSanitizer },
69+
{ provide: DOCUMENT, useClass: NativeScriptDocument },
6270
];
6371

6472
export class NativeScriptPlatformRef extends PlatformRef {

0 commit comments

Comments
 (0)