how ionic framework get data from asp.net web api - angularjs

I've created Asp.net Web API project .
When I browse http://localhost:55858/api/myData
it returns
<ArrayOfquoteMain>
<quoteMain>
<despt>Hello , data 1</despt>
<id>1</id>
<reference>Hello data 1</reference>
</quoteMain>
<quoteMain>
<despt>Hello , data 2</despt>
<id>2</id>
<reference>Hello data 2</reference>
</quoteMain>
<quoteMain>
<despt>Hello , data 3</despt>
<id>3</id>
<reference>Hello data 3</reference>
</quoteMain>
</ArrayOfquoteMain>
I just want to show this data as a list in my ionic app .
I've created Ionic app using ionic start ionic2-http blank --v2.
But I don't know how to use with my asp.net web API.

You will need to create apiService from your ionic project.
for example:
import { Injectable } from '#angular/core';
import { HttpClient, HttpParams} from '#angular/common/http';
#Injectable()
export class apiService{
constructor(private http: HttpClient) { }
serviceBaseUrl:string = http://localhost:55858/';
getData(){
let apiUrl = `${this.serviceBaseUrl}api/myData`;  
return this.http.get<any>(apiUrl);
}
}
Which you will then call it from any component using below code:
getData() {
this.apiService.getData().subscribe(
data => {
var myData = data;
console.log(myData);
},
error => console.error(error),
() => {
})
}

Is the error you are getting No 'Access-Control-Allow-Origin'...? If so you need to handle CORS in your ionic project.
CORS is only an issue when we are running or testing our app when running ionic serve.
To enable this in your ionic project, modify the ionic.config.json to include the proxies tag:
{
"name": "myionicproj",
"app_id": "",
"v2": true,
"typescript": true,
"proxies": [
{
"path": "/api",
"proxyUrl": "http://localhost:55858/api"
}
]
}
The proxy URL is the url of your .NET web api running locally. You can replace it with your environment url.
To view the results in console.log in your typescript class:
import { Component } from '#angular/core';
import {Http} from "#angular/http";
import 'rxjs/add/operator/map';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public http: Http) {
this.http.get('http://localhost:8100/api/myData').map(res => res.json()).subscribe(data => {
console.log(data);
});
}
}
http://localhost:8100 is your ionic localhost. It proxy the .net web api http://localhost:55858/api end point via your local ionic server http://localhost:8100/api

Related

Access to XMLHttpRequest at 'http://localhost:8082/kanchiwork/' from origin 'http://localhost:4200' has been blocked by CORS policy

When I tried to pass values from one server to other server am getting error as "Access to XMLHttpRequest at 'http://localhost:8082/kanchiwork/' from origin 'http://localhost:4200' has been blocked by CORS policy". My .ts file code
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class PeopleService {
constructor(private http:HttpClient) { }
fetchPeople(): Observable<Object>{
return this.http.get('http://localhost:8082/kanchiwork/');
//return this.http.get('assets/response.json');
}
}
where as if I placed the json file(response.json) in assets folder, it is working fine. I have followed the instruction given under the heading "Using corporate proxy" in the below URL, but still problem exists.
URL : https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md
For developing, You can define a proxy.dev.conf.json file to manage your request with Angular cli. eg: ng serve --open --proxy-config ./proxy.dev.conf.json
// config
[
{
"context": [
"/api/**"
],
"pathRewrite": {
"^/api": ""
},
"ws": false,
"target": "http://localhost:8082",
"secure": false,
"changeOrigin": true,
"logLevel": "debug"
}
]
// the service file
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class PeopleService {
constructor(private http:HttpClient) { }
fetchPeople(): Observable<Object>{
return this.http.get('/api/kanchiwork/');
//return this.http.get('assets/response.json');
}
}
Venkat, its not your fault because backend uses allow cross origin functionality on his side so that frontend not getting CORS error..
its error comes when you comes different url or port like cross domain.
Generally CORS error Means - CROSS ORIGIN RESOURCE SHARING it helps us to block request from Unwanted Sources, Which inturn increases security to our application, Your backend develepors should allow your url,
eg: if your backend developed in node js ask your team to add this code
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'example.com');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
//...
app.configure(function() {
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'cool beans' }));
app.use(express.methodOverride());
app.use(allowCrossDomain);
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
The proxy.conf path proposed by #xsong is correct, you just need to tweak it a little. First: don't hardcode the API path in the app itself (it's good practice anyway, regardless of proxy/no proxy/CORS/no CORS), put it in the environment.ts file. For developer build, you may define it simply as apiUrl: "/api".
Then, in your service(s), import the environment, send your requests at ${environment.apiUrl}/the-rest/of-the-path. And the third piece, you might need to rewrite path in the proxy.conf:
{
"context": [
"/api/**",
],
"target": "http://localhost:8082",
"secure": false,
"changeOrigin": true,
"logLevel": "debug",
"pathRewrite": {
"^/api": ""
}
}
It gets works by updating the files to the below ones.In proxy.config.json I updated the code as
{
"/api": {
"target": "http://localhost:8082",
"secure": false
},
"logLevel": "debug"
}
and in service file
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class PeopleService {
constructor(private http:HttpClient) { }
fetchPeople(): Observable<Object>{
return this.http.get('/api/kanchiwork/');
//return this.http.get('assets/response.json');
};
}
This code works for me and Thanks #xsong for your suggestions.

Ionic app shows not http provider error

I am trying to implement a http request in ionic framework 3.1 application. I have created a provider named apidata using ionic g provider apidata command after which i created the following function in it that calls the api and logs the data returned by it on console.
getremotedata(){
console.log(this.http.get('https://reverie.oiamigotech.com/wp-json/wc/v2/products/?consumer_key=ck_xyz&consumer_secret=cs_xyz'));
}
and have also imported the http package in the header as import { Http } from '#angular/http';
after which I updated the app.module.ts file to import the provider as import { ApidataProvider } from '../providers/apidata/apidata'; and also added the same to the provider list as providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
ApidataProvider
]
now when i try to call the same from the home page after importing the package and using the following function and constructor definition
constructor(public navCtrl: NavController,public ApidataService: ApidataProvider) {
}
ionViewDidLoad(){
this.ApidataService.getremotedata();
}
It generated the following error Uncaught (in promise): Error: No provider for Http!
referred to https://www.youtube.com/watch?v=vuc4dp0qHSc for instructions about integration.
I am new to ionic and am unable to find and debug the issue. Any suggestions are greatly welcomed.
import HttpModule and add it in app.module.ts page under imports like this,
import { HttpModule } from '#angular/http';
imports: [
BrowserModule,
HttpModule,
IonicModule.forRoot(MyApp)
]
remove any other http imports in your app.module.ts page and that should work

Angular 2 DI, use a custom Http

I have a service that uses Http:
import { Injectable } from '#angular/core';
import { Inject } from '#angular/core';
import { Http, Headers, Response } from '#angular/http';
#Injectable()
export class OrdersService {
constructor(#Inject(Http) private http:Http) {}
...
}
And a component that uses it
import { Component } from '#angular/core';
import { FormBuilder, Validators } from '#angular/common';
import { HTTP_PROVIDERS } from '#angular/http';
import { Router} from '#angular/router';
import { OrdersService } from '../services/orders.service'
#Component({
selector: 'login',
templateUrl: './login.component.html',
providers: [
HTTP_PROVIDERS, //{ provide: Http, useClass: Http }
AuthService, AuthStore,
OrdersService
]
})
export class LoginComponent {
constructor(private authService: AuthService, private ordersService: OrdersService){}
....
}
This works. I have some commented out text { provide: Http, useClass: Http }. I want to provide my own class here that extends Http, but still has all the same dependancies. The first step I'm taking here is to explicitly use Http.
As soon as I un-comment this text (and add an http import), everything breaks. I get the error "No provider for ConnectionBackend". It appears that HTTP_PROVIDERS has just stopped working as a provider.
How do I make this explicit use of Http work?
How do I use my own CustomHttp and use the providers in HTTP_PROVIDERS?
From Angular 2.1.1 and above syntax for provide option was changed after angular2 team introduce new modules concept. Below you will find correct syntax how to add your own custom provider for Http in your app.module.ts
export function httpFactory(backend: XHRBackend, defaultOptions: RequestOptions) {
return new CustomHttp(backend, defaultOptions);
}
...
providers: [
{provide: Http,
useFactory: httpFactory,
deps: [XHRBackend, RequestOptions]
}
]
You can also verify the angular2 documentation here: https://angular.io/docs/ts/latest/api/http/index/XHRBackend-class.html
If you want to implement you own CustomHttp class I will recommend you to read Thierry Templier article when step by step he is introducing how to do that.
Implementing CustomHttp for angular2 this is very helpful article which is describing how to extend to intercept request calls and add custom handling errors.
When using your own CustomHttp, you don't need to use HTTP_PROVIDERS, you need to do the following (in your app.module.ts if you are using RC5 or in your main.ts if you are using RC4):
providers: [
ConnectionBackend,
provide(
Http, {
useFactory: (
backend: XHRBackend,
defaultOptions: RequestOptions) =>
new CustomHttp(backend, defaultOptions),
deps: [XHRBackend, RequestOptions]
}),
]
I had the same problem, this fixed it for me.
Edit:
You don't need to import HTTP_PROVIDERS if you are using RC5 because you will import HttpModule, but I don't exactly remember if you need HTTP_PROVIDERS in RC4. You will probably need it.
If you don't want to change the implementations of XHRBackend and RequestOptions you can do it simplier like:
providers: [
{provide: Http, useClass: MyCustomHttp}
]

Angular2 http does not include the X-XSRF-TOKEN [duplicate]

In Angular1 the problem can be solved by configuring $http-provider. Like:
app.config(function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
});
What is a good practice to do the same in Angular2?
In Angular2 to work with http requests we need to use class Http. Of course that's not a good practice to add CSRF-line to each call of post-function.
I guess in Angular2 I should create own class that inherits Angular2's Http class and redefine the post-function. Is it the right approach or is there a more elegant method?
Now that Angular 2 is released the following seems to be the correct way of doing this, by using CookieXSRFStrategy.
I've configured my application to have a core module but you can do the same in your main application module instead:
import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '#angular/core';
import { CommonModule } from '#angular/common';
import { HttpModule, XSRFStrategy, CookieXSRFStrategy } from '#angular/http';
#NgModule({
imports: [
CommonModule,
HttpModule
],
declarations: [ ],
exports: [ ],
providers: [
{
provide: XSRFStrategy,
useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken')
}
]
})
export class CoreModule {
},
Solution for Angular2 is not as easy as for angular1.
You need:
Pick out csrftoken cookie value.
Add this value to request headers with name X-CSRFToken.
I offer this snippet:
import {Injectable, provide} from 'angular2/core';
import {BaseRequestOptions, RequestOptions} from 'angular2/http'
#Injectable()
export class ExRequestOptions extends BaseRequestOptions {
constructor() {
super();
this.headers.append('X-CSRFToken', this.getCookie('csrftoken'));
}
getCookie(name) {
let value = "; " + document.cookie;
let parts = value.split("; " + name + "=");
if (parts.length == 2)
return parts.pop().split(";").shift();
}
}
export var app = bootstrap(EnviromentComponent, [
HTTP_PROVIDERS,
provide(RequestOptions, {useClass: ExRequestOptions})
]);
Victor K's answer is perfectly valid however as of angular 2.0.0-rc.2, a preferred approach would be to use CookieXSRFStrategy as below,
bootstrap(AngularApp, [
HTTP_PROVIDERS,
provide(XSRFStrategy, {useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken')})
]);
For later versions of angular you cannot call functions in decorators. You have to use a factory provider:
export function xsrfFactory() {
return new CookieXSRFStrategy('_csrf', 'XSRF-TOKEN');
}
And then use the factory:
providers: [
{
provide: XSRFStrategy,
useFactory : xsrfFactory
}],
Otherwise the compiler will tell you off.
What I have also seen is that ng build --watch will not report this error until you kick it off again.
I struggled with this for a few days. The advice in this article is good, but as of August, 2017 is deprecated (https://github.com/angular/angular/pull/18906). The angular2 recommended approach is simple, but has a caveat.
The recommend approach is to use HttpClientXsrfModule and to configure it to recognize django's default csrf protection. According to the django docs, django will send the cookie csrftoken and expect the client to return the header X-CSRFToken. In angular2, add the following to your app.module.ts
import { HttpClientModule, HttpClientXsrfModule } from '#angular/common/http';
#NgModule({
imports: [
HttpClientModule,
HttpClientXsrfModule.withOptions({
cookieName: 'csrftoken',
headerName: 'X-CSRFToken',
})
], ...
The caveat is that angular2's XSRF Protection only applies to mutating requests:
By default, an interceptor sends this cookie [header] on all mutating requests
(POST, etc.) to relative URLs but not on GET/HEAD requests or on
requests with an absolute URL.
If you need to support an API that performs mutation on GET/HEAD, you will need to create your own custom interceptor. You can find an example and a discussion of the issue here.
Victor K had the solution, I'll just add this comment here as to what I did:
I created the component "ExRequestOptions" as Victor K said, but I also added a method "appendHeaders" to that component:
appendHeaders(headername: string, headervalue: string) {
this.headers.append(headername, headervalue);
}
Then I had this in my main.ts:
import {bootstrap} from 'angular2/platform/browser'
import {AppComponent} from './app.component'
import {HTTP_PROVIDERS, RequestOptions} from 'angular2/http';
import 'rxjs/Rx';
import {ExRequestOptions} from './transportBoxes/exRequestOptions';
import {provide} from 'angular2/core';
bootstrap(AppComponent,[ HTTP_PROVIDERS,
provide(RequestOptions, {useClass: ExRequestOptions})]);
I'm not sure the bootstrapping had any effect, so i also did this where
I would post data:
let options = new ExRequestOptions();
options.appendHeaders('Content-Type', 'application/json');
return this.http.post('.....URL', JSON.stringify(registration),
options)
Currently, I solve anything with custom headers using a wrapper service around the Http Service. You can add whatever header manually and inject additional services for storing/retrieving values. This strategy also works for JWTs, for example. Have a look at the code below, I hope it helps.
import {Injectable} from '#angular/core';
import {Http, Headers, RequestOptions} from '#angular/http';
#Injectable()
export class HttpService {
constructor(private http: Http) {
}
private get xsrfToken() {
// todo: some logic to retrieve the cookie here. we're in a service, so you can inject anything you'd like for this
return '';
}
get(url) {
return this.http.get(url, this.getRequestOptions())
.map(result => result.json())
.catch(error => error.json());
}
post(url, payload) {
return this.http.post(url, payload, this.getRequestOptions())
.map(result => result.json())
.catch(error => error.json());
}
private getRequestOptions() {
const headers = new Headers({'Content-Type': 'application/json', 'X-XSRF-TOKEN': this.xsrfToken});
return new RequestOptions({headers: headers});
}
}

I need to do a http request to a mail chimp subscription list via a component post

I need to do a http request to a mail chimp subscription list via a component post
I've read the mail chimp documentation and couldnt find anything on this.
I also tried their mail chimp embedded form in an angular 2 html5 view but that doesnt work for some weird reason.
So I've resulted to doing a http request to the subscribe list instead and I'm having trouble getting that working.
I'm using typescript, angular2 and mail chimp
This is my code so far:
subscribe = () => {
var url = "https://mysubscriptionlist.us10.list-manage.com/subscribe/post?u=b0c935d6f51c1f7aaf1edd8ff&id=9d740459d3&subscribe=Subscribe&EMAIL=" + this.email;
this.jsonp.request(url).subscribe(response => {
console.log(response);
});
}
This is my current console log error in chrome:
Uncaught SyntaxError: Unexpected token <
I finally found out how to fix your issue. You need to use the Jsonp support of Angular2.
Your address supports Jsonp by adding a c query parameter to your URL and switching https://mysubscriptionlist.us10.list-manage.com/subscribe/post by https://mysubscriptionlist.us10.list-manage.com/subscribe/post-json. You need to put the JSONP_CALLBACK value in it (see this issue: https://github.com/angular/angular/issues/5613).
In this case, you will have the following response payload:
JSONP_CALLBACK (
{
"result": "success",
"msg": "Almost finished... We need to confirm your email address. To complete the subscription process, please click the link in the email we just sent you."
}
)
After having registered JSONP_PROVIDERS when calling the bootstrap function:
import {bootstrap} from 'angular2/platform/browser'
import {JSONP_PROVIDERS} from 'angular2/http'
import {AppComponent} from './app.component'
bootstrap(AppComponent, [ JSONP_PROVIDERS ]);
You can then execute your request using an instance of the Jsonp class you injected from constructor:
import {Component} from 'angular2/core';
import {Jsonp} from 'angular2/http';
#Component({
selector: 'my-app',
template: `
<div>
Result: {{result | json}}
</div>
`
})
export class AppComponent {
constructor(jsonp:Jsonp) {
var url = 'https://mysubscriptionlist.us10.list-manage.com/subscribe/post-json?u=(...)&subscribe=Subscribe&EMAIL=my#email.com&c=JSONP_CALLBACK';
jsonp.request(url, { method: 'Get' })
.subscribe((res) => {
this.result = res.json()
});
}
}
See this plunkr for a working sample: http://plnkr.co/edit/dqreqBL6kyNkR8Z2wgGR?p=preview

Resources