Angular 7: How to increase the time of an angular request - javascript

I need to increase the request time of the angular app because using slow internet connections timeout happens.
I tried the code below and had an error.
this.http.post(url, body, { headers: headers })
.timeout(100, this.handleTimeout)
.map(response =>{
return response;
})
.catch(this.handleErrors);
Property 'timeout' does not exist on type
'Observable'.ts(2339)
Not success using interceptor too
#Injectable()
export class AngularInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).timeout(5000);
}
Property 'timeout' does not exist on type
'Observable>'.ts(2339)
Thanks

The final solutions that works for me:
import { timeout} from 'rxjs/operators';
return this.http.get(`${url}`).pipe(
timeout(1000)
);
Thanks to all for the help.

With Rxjs 6, you will have to use a .pipe and then use an operator like .timeout
So your implementation should look like:
import {
timeout,
map,
catch
} from 'rxjs/operators';
this.http.post(url, body, { headers: headers })
.pipe(
timeout(100, this.handleTimeout),
map(response =>{
return response;
}),
catch(this.handleErrors);

Related

You provided 'undefined' where a stream was expected. in token interceptor

I am trying to make an interceptor to refresh the token, but it throws me this error and I don't know why
ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
token-interceptor.service.ts
import { Injectable } from '#angular/core';
import { AuthService } from './auth.service';
import { HttpClient, HttpErrorResponse, HttpHandler, HttpInterceptor, HttpRequest } from '#angular/common/http';
import { environment } from 'src/environments/environment';
import { catchError, map} from 'rxjs/operators';
import { throwError } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class TokenInterceptorService implements HttpInterceptor {
constructor(
private auth: AuthService,
private http: HttpClient
) { }
intercept(req: HttpRequest<any>, next: HttpHandler) {
return next.handle(req).pipe(
catchError((err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.url.includes('signin') || err.url.includes('refreshToken')) {
return next.handle(req)
}
//if error is not about authorization
if (err.status !== 401) {
return next.handle(req)
}
this.renewToken(req).subscribe(request => {
return next.handle(request)
})
} else {
return throwError(err)
}
})
)
}
renewToken(req: HttpRequest<any>) {
return this.http.get(`${environment.API_URL}/refreshToken`, { withCredentials: true }).pipe(
map((res: any) => {
//update access token
this.auth.setToken(res.token)
return req.clone({
setHeaders: {
authorization: `Bearer ${res.token}`
}
})
})
)
}
}
Ignore this: It looks like your post is mostly code; please add some more details. It looks like your post is mostly code; please add some more details.
this piece of code is wrong:
this.renewToken(req).subscribe(request => {
return next.handle(request)
})
istead it should be:
return this.renewToken(req).pipe(switchMap(request => next.handle(request)));
you are just returning nothing in your variant, that is why it doesn't work.
also the whole logic of token interpceptor seems weird to me. I believe you should rethink about how you want it to work. for now as I see you sending request without token and in almost all cases you are sending it again unmodified, and the one that I fixed above will send it again with token. Wouldn't it be right to add token every time, and only send it 2nd time if token is outdated?

Unit Testing with Angular 7

I am trying to write unit test for this angular script:
export class DataService {
private csrfToken: string = '';
private isContentShow: BehaviorSubject<boolean> = new BehaviorSubject(true);
constructor(private http: HttpClient, private cookieService: CookieService) {
this.token = this.cookieService.get('token');
}
public createData(data: Data) {
try {
this.http.post( url,
data,
{
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': this.token
})
})
.subscribe(
data => {
this.isContentShow.next(true);
},
err => {
this.showError();
},
() => console.log('Request Complete')
);
return true;
} catch {
this.showError();
}
}
public getIsContentShow(): Observable<boolean> {
return this.isContentShow.asObservable();
}
}
The test that I had so far and its running as expected.
it('#getIsContentShow should return value from observable',
(done: DoneFn) => {
service.getIsContentShow().subscribe(value => {
expect(value).toBe(true);
done();
});
});
However I am trying to write the test for createData() function
I am able to mock the HttpClient using HttpClientTestingModule however I don't know how to handdle the CookieService and token ?
Thanks
You can use spies to spy on the cookieService get method. This way, you can write your unit test to test the combinations of returns you say the cookieService can provide.
This link says that you can spy on the prototype of the method in order to handle it how you like in the constructor.
it(
"should call #getGeneralStats in the constructor",
inject(
[CookieService, HttpClient],
(cookieService: CookieService, http: HttpClient) => {
let mySpy = spyOn(cookieService, 'get').and.returnValue(<your value>);
dataService = new DataService(http, cookieService);
expect(mySpy).toHaveBeenCalled();
}
)
);
For you, this may depend on how you're writing your tests. The example shows the service being instantiated like new ServiceName, but it's also possible to use dependency injection to get the service. If you're using DI for the service you are testing, I'd have to research more how to do this (others please feel free to add your answer if you know how to do that)!

Where is the 'req' parameter defined?

I'm trying to implement an authentication scheme described here.
I'm struggling to find where the req parameter is defined in the code below. My code would not compile as it is not currently defined. This could be a typo in his code. I looked through the comments but nobody seems to have pointed that out:
// src/app/auth/jwt.interceptor.ts
// ...
import 'rxjs/add/operator/do';
export class JwtInterceptor implements HttpInterceptor {
constructor(public auth: AuthService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// do stuff with response if you want
}
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
// redirect to the login route
// or show a modal
}
}
});
}
}"
Can someone point out what i'm missing?
Many thanks in advance.
Looks like a typo to me. The intercept function provides a parameter request - it should probably be referring to that instead of req.
The parameter must read as request as below
return next.handle(request)
.do(event => {
if ()

How to consume REST API with Angular2?

This is my demo code:
products.service.ts
getProducts(){
this.headers = new Headers();
this.headers.append("Content-Type", 'application/json');
this.headers.append("Authorization", 'Bearer ' + localStorage.getItem('id_token'));
return this.http.get('http://mydomain.azurewebsites.net/api/products',{headers:headers}).map(res => res.json().data);
}
products.component.ts
constructor(private productsService: ProductsService) { }
ngOnInit() {
this.productsService.getProducts().subscribe((res) => {
console.log(res);
});
}
Is it nescessary to import something in the ngModule decorator to consume a REST API or my code is wrong? I can get the desired data with Postman Chrome Extension but not with Angular 2 code.
I hope to have explained my problem well.
Update
These are the errors i get:
Sorry for making you waste your time.
This was the problem:
app.module.ts
providers: [
ProductsService,
// { provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
// { provide: SEED_DATA, useClass: InMemoryDataService } // in-mem server data
]
After commenting the in-mem server and and the in-mem server data the problem dissapeared.
You're not setting the headers in the request. You declare the Headers object but you don't actually do anything with it.
You need to set them in the get function like this:
return this.http
.get('http://mydomain.azurewebsites.net/api/products', { headers: headers })
.map(res => res.json().data);
I'd suggest you use ngx-rest-ex: https://www.npmjs.com/package/ngx-rest-ex
npm i -S ngx-rest-ex
It's convenient, you just need to specify the corresponding decorator on top of the method and the return type, it will replace your method body. The return type can be either Promise or Observable depending on the HTTP METHOD annotation that you specified.
My demo code for your case:
import { Injectable, Injector } from '#angular/core';
import { BaseUrl, GET, RESTClient } from 'ngx-rest-ex';
import { Product } from './models';
#Injectable({
providedIn: 'root'
})
#BaseUrl('http://mydomain.azurewebsites.net/api/')
export class ApiService extends RESTClient {
constructor(injector: Injector) { super(injector); }
protected getDefaultHeaders() {
return {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('id_token')
};
}
#GET('products')
getProducts(): Promise<Product[]> {
return;
}
}

Angular 2 http post request is not being called out

I am using angular 2 to make a get request and a post request. My get request works fine, but for my post, I do not see the request is made when checking my Firebug Net panel.
The code methods look like follows. I also have subscribe methods invoking them from a component class.
import {Injectable} from "angular2/core";
import {Http, Response, Headers, RequestOptions, Jsonp, URLSearchParams} from "angular2/http";
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
#Injectable()
export class MyService{
constructor (private _http: Http){}
testPost(){
var json = JSON.stringify({"userId": 111, "givenName": "CZ"});
var body = "json="+json;
var headers = new Headers({ 'Content-Type': 'application/json' });
var options = new RequestOptions({ headers: headers });
return this._http.post("http://mylocal.post.url", body, options)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
alert("test whether this method is reached");
let body = res.json();
return body.data || { };
}
private handleError (error: any) {
alert("test whether this method is reached");
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);
}
//testGet method is running well
testGet(link:string){
return this._http.get(link)
.map(res => res);
}
}
my subscribing method onTestPost(), which is assigned to a button on the page.
onTestPost(){
this.myService.testPost()
.subscribe(
data => this.getData = JSON.stringify(data),
error => alert(error),
() => console.log("Finished")
);
}
I put an alert statement at the beginning of two helper methods. None of the alerts is reached. And I don't see any request called to the my local post url when debugging with Firebug.
While my testGet method works correctly, I just don't know what is missing for the testPost.
I think your subscribe methods are the issue here. Please make sure subscribe is called.
"This observable is cold which means the request won't go out until
something subscribes to the observable."
See https://angular.io/docs/ts/latest/guide/server-communication.html
testPost() : Observable <Response> //import{Response} from '#angular/http'
{
var json = JSON.stringify({"userId": 111, "givenName": "CZ"});
var headers = new Headers({ 'Content-Type': 'application/json' });
var options = new RequestOptions({ headers: headers });
return this._http.post("http://mylocal.post.url/api",JSON.stringify(json), options)
.map((res:Response)=>res.json())
.catch(this.handleError);
}

Categories

Resources