How to fire an ajax request in Angular 2? - javascript

I have service defined in Angular 2 like this:
import { Inject } from 'angular2/angular2';
import { Http ,Headers , HTTP_PROVIDERS } from 'angular2/http';
export interface CourseInterface {
courseId: number,
coursePrice: number,
authorName: string
}
export class CourseDetailsService {
http: Http;
constructor(#Inject(Http) Http) {
console.log(Http)
this.http = Http;
}
load() {
console.log("came here in service")
var headers = new Headers();
headers.append('Authorization', <my username password>);
this.http.get('https://some.api',{
headers : headers
}).map(res => console.log("Response came!!!"))
console.log("done . . .")
}
}
and in another component, I use this service like this:
import {CourseInterface, CourseDetailsService} from '../services/course';
#Component({
selector: 'dashboard',
viewBindings: [CourseDetailsService]
})
#View({
template: `
<h1>Dashboard page laoded</h1>
`
})
export class Dashboard {
constructor(service: CourseDetailsService) {
service.load();
}
}
and while running the application, I can see my Dashboard component gets displayed on the screen. But however from the CourseDetailsService, no http calls are getting fired.
But in the console I could able to see the following printed:
came here in service
done . . . .
But in my chrome networks tab, I couldn't able to see any request fired to the specified url. Where I am making mistake?
I'm using Angular 2 Alpha 47

Basically the part that triggers the request itself it's the subscribe, so to make it work you have to add it.
// Service
load() {
var headers = new Headers();
headers.append('Authorization', <my username password>);
return this.http.get('https://some.api',{
headers : headers
}).map(res => console.log("Response came!!!"))
}
// Component
// 'subscribe' triggers the request!
service.load().subscribe((result) => /* do something with result */);

Related

Change axios BaseURL dynamically based on select html element

I have a vuejs app that talks to multiple identical backends that are geographically separate. Each endpoint has a unique URL - example:
export const SERVICE_BASE_API_URLS = [
{ name: 'Site A', endpoint: 'http://api.a.service.com/api/v1/' },
{ name: 'Site B: 'http://api.b.service.com/api/v1' },
}
I am allowing users to select the endpoint they'd like to interact with via a select box. I'd like to set up the selected URL to be used in any further interactions globally for axios. I thought setting up Vue.Prototype.$current_endpoint would work.
So I have the onchange action of the select element store it's endpoint value in Vue.Prototype.$current_endpoint.
I have to setup an axios instance that is used by multiple endpoint classes once e.g. auth-header.js is imported by authenticate.js
import axios from 'axios';
import * as URLConstants from '../configs/urls';
export const axios_instance = axios.create({
//baseURL: URLConstants.Service_BASE_API_URL, // this was earlier set in .env. But this would be statically set for the vue instance
baseURL: Vue.prototype.current_api_endpoint
})
axios_instance.interceptors.request.use(
function(config) {
if (JSON.parse(localStorage.getItem('user')) && JSON.parse(localStorage.getItem('user')).access_token) {
const token = JSON.parse(localStorage.getItem('user')).access_token
config.headers["JWTAuthorization"] = 'Bearer ' + token;
}
return config;
},
function(error) {
return Promise.reject(error);
}
);
So later on in interact-with-service.js I have
import {
axios_instance
} from './auth-header';
import APIMixin from './mixin';
class ExpenseService extends APIMixin {
get(params) {
...
...
return axios_instance
.get("expense" + params)
.then(this.handleResponse);
}
However, I'm finding it practically impossible to set up the axios base url properly. Can someone please show me the way? :)
You can change default base url https://axios-http.com/docs/config_defaults
axios_instance.defaults.baseURL = "selected url";

How to make a non-ajax HTTP Post Request in Angular 4

My question is very simple... How can make an Post HttpRequest with params in angular 4. I could not find an example ... the examples I find are using HttpClient, but it's not what I need
Without XHR or fetch (aka AJAX), you're not able to instruct the browser to make an HTTP POST request. By navigating to some URL, the browser makes a HTTP GET request.
If you want to send an HTTP POST request directly from the browser, you'll need to use XHR/fetch.
Circling back to this, although I managed to create a test with a get method using the HttpRequest class I was having trouble with using the POST method. Instead I used the HttpModule from #angular/http and the accompanying classes. Then I tried adding an e.preventDefault. Try that and see if it works for you. Additionally you may need to use pure JS methods here.
in AppComonent
import {Http, Response, RequestOptions, Headers, Request, RequestMethod} from '#angular/http';
import { Component, OnInit } from "#angular/core";
export class AppComonent implements OnInit {
dataBody =JSON.stringify({
title: "foo",
body: "bar",
userId: 1
});
headers;
requestOptions;
requestMethod;
Response;
constructor(private http: Http) {}
ngOnInit(
) {
}
onPreventDefault(e){
e.preventDefault();
}
onPostData(){
return this.postRequest('https://jsonplaceholder.typicode.com/posts', this.dataBody);
}
postRequest(url,data) {
this.headers = new Headers();
this.headers.append("Content-Type", 'application/json');
this.requestOptions = new RequestOptions({
method: RequestMethod.Post,
url: url,
headers: this.headers,
body: data
});
return this.http.request(new Request(this.requestOptions))
.subscribe((res: Response) => {
if (res) {
console.log(res);
}
});
}
}
in module.ts
import { HttpModule } from '#angular/http';
imports: [HttpModule];
in app-component.html
<form (ngSubmit)="onPostData()" (submit)="onPreventDefault($event)" target="_blank" action="http://localhost:3000/api/users" >
<button type="submit" >Submit</button>
</form>
in app.module.ts
import { HttpClientModule } '#angular/common/http';
#NgModule ({
imports: [HttpClientModule]
})
in app.component.ts
import { HttpClient } from '#angular/common/http';
export class AppComponent {
constructor(private http: HttpClient) {
this.http.post('http://someurl/endpoint', {postData1: 'avb', postdat2: 'xyx}).subscribe(res => console.log(res), error => console.log(error));
}
}

Angular - Display server error in component

I'm currently working on a register page and therefore, I need to post my data to the server. The client-side validation and server-validation works. I know I can handle the client-side errors like *ngIf="(emailAddress.errors?.required || emailAddress.errors?.email) && emailAddress.touched". But how to handle the server-side errors?
In my service, if an error occurs, I simply give it into the component by return throwError(error);
But how can I know to display the specific error in my component if for example there is already someone with this email address? And how do distinguish between email/password validation errors server side?
Depends on the complexity and modules you have.
If you use any kind of state management library such as ngrx or ngxs, I suggest you do as follow:
Define State with a property 'error' which keeps track of the latest server-error.
Api call executed via actions and error is caught and stored to state also via actions. (Do whatever error mapping before saving the error to your State)
Use selectors for component to receive error stream from State.
If you don't have any state management library, you can create a BehaviorSubject within singleton service, and use it to publish server-error as soon as you got into any catchError context.
This way you can write your own http interceptor and have your response inside your component. Also in your component you know your http response is success or error.
You can implement other Http calls(GET, PUT, etc) and also handle your general errors in handleError() function.
app.module.ts
export class AppModule {
constructor() {}
imports: [
HttpClientModule,
],
providers: [
{
provide: Http,
useFactory: httpFactory,
deps: [HttpHandler]
},
],
}
export function httpFactory(httpHandler: HttpHandler) {
return new Http(httpHandler);
}
http.service.ts
export class Http extends HttpClient {
constructor(handler: HttpHandler) {
super(handler);
}
postCall(url: string, body, options?): Observable<any> {
return super.post(url, body, options)
.pipe(
tap(response => { console.log(response) }),
catchError(this.handleError(error)));
}
private handleError<T>(result?: T) {
return (error: any): Observable<T> => {
console.log(error);
return of(result as T);
};
}
}
your.component.ts
export class YourComponent {
constructor(private http: Http) {}
this.http.postCall('URL', {}).subscribe(response => {
if (response instanceof HttpErrorResponse) {
// Your Response is error
} else {
// Your Response is your desired result
}
}

Angular 2 get image src from authorized request

I'm using angular2-jwt to authorize the requests. I've got a get request which retrieves multiple documents from the API.
A document can have multiple images which also need to be fetched using an authorized request.
So obviously calling them directly with doesn't work.
I followed this example: https://stackoverflow.com/a/40862839/909723
I've got two questions:
Without the async i get : GET http://localhost:4200/[object%20Object] 404 (Not Found)
And with the async i get : Invalid argument '[object Object]' for pipe 'AsyncPipe' I tried it with the 'data:image/jpg;' and without
Part of the template
<md-card *ngFor="let document of documents">
<md-toolbar color="accent" *ngIf="getDocName(document)">
<span class="nowrap">{{getDocName(document)}}</span>
<span class="country-full-width"></span>
</md-toolbar>
<md-card-content>
<div *ngFor="let image of getImages(document)">
<img class="image" [src]="getImageSrc(image.image_id) | async" />
</div>
</md-card-content>
</md-card>
I've got a service which uses angular2-jwt - AuthHttp
#Injectable()
export class ImageService {
constructor(public authHttp: AuthHttp, public http: Http, public sanitizer: DomSanitizer) {}
getImageSrc(id, type){
let url = Config.apiUrl + "/images/" + id + "/thumb.jpg"
let headers = new Headers();
headers.append('Content-Type', 'image/jpg');
return this.authHttp.get(url, {
headers: headers,
responseType: ResponseContentType.Blob
})
.map(res => {
return new Blob([res["_body]"]], {
type: res.headers.get("Content-Type")
});
})
.map(blob => {
var urlCreator = window.URL;
return this.sanitizer.bypassSecurityTrustUrl(urlCreator.createObjectURL(blob));
})
}
}
This is the function called in the template
getImageSrc(id)
{
return this.imageService.getImageSrc(id)
//.subscribe (
// data => data,
// err => console.log(err)
//);
}
Hope someone can help
I have faced the same problem and this solution helped: http://blog.jsgoupil.com/request-image-files-with-angular-2-and-an-bearer-access-token
Although you may need to change the way in which options are added to http request (in UrlHelperService) according to your angular version 2/4.
Also you need to change:
Observable
to
Observable<any>
all ower the place.
And
private _result: BehaviorSubject = new BehaviorSubject(null);
to
private _result: BehaviorSubject<any> = new BehaviorSubject('');

Injecting and using Http Angular2

I have a service class that should call an api and return the results:
import {Component, View} from 'angular2/angular2';
import { Inject} from 'angular2/di';
import {Http} from 'angular2/http';
var httpMap = new WeakMap<ScheduleService, Http>();
export class ScheduleService {
meetings: Array<any>;
http: any;
constructor(#Inject(Http) http:Http){
httpMap.set(this, http);
this.http = http;
//http.get('/api/sample')
// .map(response => response.json())
// .subscribe(data => {
// this.serverData = data;
// });
}
getMeetings(){
var path = '/api/meetings/';
return httpMap.get(this).get(path);
}
}
The service class is being called and injected correctly. The issue I am having is that when ever I call the getMeetings method it never makes the request to /api/meetings. If you guys notice in the constructor there is a get request to /api/sample that works perfectly if I uncomment it and run the program I check my network tab and I can see the request was made.
Looks like http.get(path) doesn't send off a request unless you call http.get(path).subscribe(); even if you don't do anything with the response.
Plunker: https://plnkr.co/edit/b1fxoIUy31EHTC84U344?p=preview
In the Plunker, open the network view in the console and click the With Subscribe / Without Subscribe buttons for comparison.

Categories