Angular2 HTTP Request Providers - rest

I want to make connection between my angular app and my REST API.
Here it returns JSON http://is.njn.mvm.bg/check. So my question is which providers do I need because I include in app.module, but it still doesn't work.
import { HttpModule} from '#angular/http';
I am using Angular2 HTTP tutorial
private heroesUrl = 'http://is.njn.mvm.bg/check'; // URL to web API
constructor (private http: Http) {}
getHeroes (): Observable<Hero[]> {
return this.http.get(this.heroesUrl)
.map(this.extractData)
.catch(this.handleError);
}
I am getting XMLHttpRequest cannot load http://localhost:8000/da. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

you are using the http request wrong. plz use following code.
app.component.ts
//our root app component
import { Component } from '#angular/core'
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
#Component({
selector: 'root',
template: `
<div>
{{people}}
{{ err}}
</div>
`
})
export class App {
people;
err;
constructor(http:Http) {
http.get('http://is.njn.mvm.bg/check').map(res => res.text()).subscribe(people => this.people = people,err=>this.err = err);
// Subscribe to the observable to get the parsed people object and attach it to the
// component
}
}
Also remember
Follow error occur in your console:
Access-control-allow-origin
For remove this error see:
chrome extension for access control

You need to put header parameter "Access-Control-Allow-Origin" in the server's HTTP response. You can't make this work from the client side only. I also had the same issue when trying to grab data from my Java JSON REST server. I am not sure what you use server side, but in Java it looks something like this:
return Response.ok() //200
.header("Access-Control-Allow-Origin", "*");
For information on this error (CORS), see this:
How does Access-Control-Allow-Origin header work?

You also need to add it to imports of #NgModule
#NgModule({
imports: [BrowserModule, HttpModule]
...
})

You module code will be like below:
#NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule,
],
declarations: [
AppComponent
],
providers: [
{provide: APP_BASE_HREF, useValue: '/'},
],
bootstrap: [AppComponent]
})
export class AppModule {
}
you service code need to similar to this
constructor(private http: Http) {
}
getCountriesByRegion(region: string) {
return this.http.get(this.countries_endpoint_url + region).map(res => res.json());
}
//you can also do like this
getHeroes(): Observable<any[]> {
return this.http.get(this.heroesUrl)
.map(this.extractData)
.catch(this.handleError);
}

You have the Angular app that's served by the server running on port 3000, but this app tries to make HTTP calls to the server running on another port 8000.
You have two options:
1. Deploy your Angular app under the server that runs on port 8000, in which case your Angular app will hit the same port it was served from.
2. Configure a proxy on the server that runs on port 3000 to allow access to port 8000.
For the second scenario, if you use Angular CLI with your project, create a file proxy-conf.json, for example:
{
 "/api": {
 "target": "http://localhost:8000",
 "secure": false
 }
}
Then sevre your Anglar app like this:
ng serve --proxy-config proxy-conf.json

Related

How to use Ionic proxy in conjunction with AWS SDK

Using Ionic 4.4.0 and aws-sdk 2.157.0. I'm trying to create an S3 bucket from my local web browser, but am running into CORS problems when attempting to run the following code, method createBucketByCompanyKey():
import { Injectable } from '#angular/core';
import * as AWS from 'aws-sdk';
#Injectable()
export class AwsProvider {
private accessKeyId:string = 'myAccessKey';
private secretAccessKey:string = 'mySuperSecret';
private region:string = 'us-east-1';
constructor() {
AWS.config.update({accessKeyId: this.accessKeyId, secretAccessKey: this.secretAccessKey, region: this.region});
}
createBucketByCompanyKey(companyKey){
let s3 = new AWS.S3();
let params = {
Bucket: companyKey,
CreateBucketConfiguration: {
LocationConstraint: this.region
}
};
s3.createBucket(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
}
}
This gives me the error
Failed to load https://s3.amazonaws.com/-KwzdjmyrHiMBCqHH1ZC: Response
to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8100' is therefore not allowed
access. The response had HTTP status code 403.
Which led me to this post here after several hours of googling. It appears I need to run ionic through a proxy. I've also tried changing my "path" to http://localhost:8100, but stuck I remain.
{
"name": "MyApp",
"app_id": "",
"type": "ionic-angular",
"integrations": {},
"proxies": [
{
"path": "/",
"proxyUrl": "https://s3.amazonaws.com/"
}
]
}
I've also come across posts telling my to download a Chrome extension that disables CORS, but that didn't work either.
Any ideas on how to setup this proxy to work with AWS' SDK?
Forget the proxies. For Mac, enter in the following in the terminal to open a Google Chrome browser with CORS disabled.
open -a Google\ Chrome --args --disable-web-security --user-data-dir
Compliments of this post.

Ionic/cloud-angular FacebookAuth gives empty error

I've added ionic cloud services to my app and want to use the native FaceBook authentication.
import { FacebookAuth } from '#ionic/cloud-angular';
this.facebookAuth.login()
When running this function on an Android phone, as expected I get the Facebook prompt to ask if my app can get permissions to read profile and email. When I click YES, the function returns an empty ERROR object:
Object {}
I'm sure I am catching it right, because when I choose CANCEL on the FB prompt, I get this error object:
Object {errorCode: "4201", errorMessage: "User cancelled dialog"}
Note: I'm using remote web inspector in chrome to see the full console. Unfortunately, as this requires a real device I can not Plunker this. However, I hope someone has an idea why this could happen. I have followed all these steps, including the FB developer settings, the hash and the ionic.io settings.
I have done that and it's working fine on the real device.If you have any question, please comment below.
Play with Git Repo
app.module.ts
import { CloudSettings, CloudModule } from '#ionic/cloud-angular';
const cloudSettings: CloudSettings = {
'core': {
'app_id': 'd32c02d2'
},
'auth': {
'facebook': {
'scope': ['public_profile', 'email']
}
}
};
#NgModule({
declarations: [
],
imports: [
CloudModule.forRoot(cloudSettings)
],
bootstrap: [IonicApp],
entryComponents: [
],
providers: [
]
})
export class AppModule { }
home.html
<button ion-button block type="button" (click)="fbLogin()">Fb Login</button>
home.ts
import { Component } from '#angular/core';
import { FacebookAuth, User } from '#ionic/cloud-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public facebookAuth: FacebookAuth, public user: User) {
}
fbLogin() {
this.facebookAuth.login();
}
}
Ok it's quite silly, but the first root cause was that the FB user I was trying to log in with was not registered as a tester. Apparently in that case, an empty error is returned by the plugin.
After adding as a tester, I received a real error (Andoird manifest dod not allow internet access). After fixing that issue, again I'm getting an empty error.
So my assumption is that some of the errors returned by FB are not well communicated by the plugin and so any other FB error can be causing this issue.
UPDATE 23/04: There seems to be a change from FB side, now the FB login screen did not succeed but gave an error about the hashing key. After fixing that issue, the FB login is working now.

Angular 2 & ionic 2 http request with basic authentification error

I have some problems with Angular 2 http get request in a ionic 2 application.
In fact I have a website (made with the Jalios CMS) which is running currently with an Apache tomcat on localhost:8080 and I want to access data from my ionic app with RESTful Web services. To access to this website the users need to log in, and their passwords can contain special charactere like #,#.:?
When I use the cURL command, I can access data without any problems. Data are returned in xml.
curl -u username:p#ssword http://localhost:8080/jcms/rest/data/Article
However in my ionic 2 application I have the following errors:
OPTIONS http:/ /localhost:8080/jcms/rest/data/Article 401 (Non-Autoris%E9). polyfills.js:3
XMLHttpRequest cannot load http:/ /localhost:8080/jcms/rest/data/Article. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http:/ /localhost:8100' is therefore not allowed access. The response had HTTP status code 401. (index):1
ERROR Response {_body: ProgressEvent, status: 0, ok: false, statusText: "", headers: Headers…}. core.es5.js:1084
my http provider: rest-service.ts
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class RestService {
constructor(public http: Http) {
console.log('Hello RestService Provider');
}
httpGet(username: string, password: string, resource: string){
let url = 'http://localhost:8080/jcms/rest/data/' + resource;
let headers: Headers = new Headers();
headers.append("Authorization", "Basic " + btoa(username + ":" + password));
return this.http.get(url, {headers: headers});
}
}
my Ionic page (component): home.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import {RestService} from "../../providers/rest-service";
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
result: Array<any>;
constructor(public navCtrl: NavController, private restService: RestService) {
this.restServiceGet();
}
restServiceGet(){
this.restService.httpGet('username', 'p#ssword', 'Article')
.map(res => res.json())
.subscribe(data => this.result = data);
}
}
Normally all have been correctly imported in the app.module.ts file. I also try to change the special character by URL Encoding (%40 for #), and replace the btoa directly by the base 64 equivalence of username:p#assword.
Can you help me to correct this errors? Especially the 401 unauthorized because I d'ont understand why it happen whereas I implemented the headers with the basic authentification. Where are my mistakes?
Thank you

Angular 2 Passing object between routes

Trying to find the answer on how to pass a common object between routes.
I have a service which store socket.io
I need to have access to that socket service across my whole site so I can listen for emits.
I have a route.ts file and I am not sure how to initialise a socket service in the root then pass it to the route when needed.
I have read the docs and I am trying to use data like below in my route.ts file:
const routes: RouterConfig = [
{ path: '', component: AppComponent },
{ path: 'function1', component: Function1Component, data: { socket: socket }},
];
However I dont know where to declare the socket service.
Thanks
In your case you are trying to pass some function reference(which is going to return object/promise/observable) from data option of route, so that would not work by passing it in data option because it does stringify the data when you ask for data by doing this.routerData.get('socket').
I strongly recommend to use resolve option of route here. resolve method would return promise/observable
Code
#Injectable()
class SocketResolver implements Resolve {
constructor(private socketService: socketService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<any> {
return this.socketService.connection();
}
}
const routes: RouterConfig = [
{ path: '', component: AppComponent },
{ path: 'function1', component: Function1Component,
resolve: { socket: SocketResolver }
}
];
Doc Link
you should not involve routing in this.
just create a service: https://angular.io/docs/ts/latest/tutorial/toh-pt4.html
SocketService.ts
import { Injectable } from '#angular/core';
#Injectable()
export class SocketService {
...
}
and inject that service in your component or other services via the constructor:
constructor(private socketService:SocketService) { }
plus you make sure your service is intialized in the bootstrap process:
bootstrap(AppComponent, [
SocketService,
... ]);
on bootstrap, angular will create a single instance of your service which will be injected into every component which has it in its constructor, therefore you have access to the same socket service from everywhere you want.

Angular2 HTTP - How to understand that the backend server is down

I am developing a front end which consumes JSON services provided by a server.
I happily use HTTP of Angular2 and I can catch errors via .catch() operator.
If I find a problem related to a specific service (e.g. the service is not defined by the server) the catch() operator receives a Response with status 404 and I can easily manage the situation.
On the other hand, if it is the server that is completely down, the catch() operator receives a Response with status code 200and no specific sign or text related to the cause of the problem (which is that the whole server is down).
On the console I see that angular (http.dev.js) writes a message net::ERR_CONNECTION_REFUSED but I do not know how to do something similar (i.e. understand what is happening and react appropriately) from within my code.
Any help would be appreciated.
If you would like to handle this event globally in your application I recommend using slightly modified Nicolas Henneaux's answer https://stackoverflow.com/a/37028266/1549135
Basically you can check for error.status === 0 which happens when the net::ERR_CONNECTION_REFUSED error occurs.
The complete module file:
import { Request, XHRBackend, BrowserXhr, ResponseOptions, XSRFStrategy, Response } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
export class AuthenticationConnectionBackend extends XHRBackend {
constructor(_browserXhr: BrowserXhr, _baseResponseOptions: ResponseOptions, _xsrfStrategy: XSRFStrategy) {
super(_browserXhr, _baseResponseOptions, _xsrfStrategy);
}
createConnection(request: Request) {
let xhrConnection = super.createConnection(request);
xhrConnection.response = xhrConnection.response.catch((error: Response) => {
if (error.status === 0){
console.log("Server is down...")
}
...
return Observable.throw(error);
});
return xhrConnection;
}
}
Module file:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { HttpModule, XHRBackend } from '#angular/http';
import { AppComponent } from './app.component';
import { AuthenticationConnectionBackend } from './authenticated-connection.backend';
#NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
],
entryComponents: [AppComponent],
imports: [
BrowserModule,
CommonModule,
HttpModule,
],
providers: [
{ provide: XHRBackend, useClass: AuthenticationConnectionBackend },
],
})
export class AppModule {
}
I have the same problem while using angular2.0.0-beta.15
It seems like this is a bug. You get http status 200 and this is not correct:
https://github.com/angular/http/issues/54
Well i have faced something similar before. I was trying to make a logging Service and a Error handling which tells the user if error happened with some requests to the server or if the whole server is down.
I used HTTP Interceptor to catch the responses here is the code:
export class HttpErrorHandlingInterceptor implements HttpInterceptor {
constructor(private logService: LogService,
private layoutStateService: LayoutStateService){}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
if (req.url) {
return next.handle(req).pipe(
map((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
return event;
}
}),catchError(err => {
if(!err.status){
this.layoutStateService.dispatchServerDown();
}else{
this.layoutStateService.dispatchAddServerError(err);
this.logService.logError(err);
}
throw err;
})
);
}
}
}
Now you can specify what should happen when Server is down according to your application.
Hope that helps.