I have ts file and I would like to create POST method inside component. I try in the way shown below unfortunately without positive results.
this.http.post("http://localhost:8000/", JSON.stringify({ body: 'String' }), {headers:{'Content-Type': 'application/json'}})
UPDATE
I have a little modified my backend logic and I realized that I don't need to send body in POST method. I can send my data in URL parameter. I would like to send GET request and assign received data to object object.sth which needs object of Isth[] type. At this moment my code looks in the way shown below. However console.log("data: "+object.sth); after assignment returns data: undefined.
this.http.get("http://localhost:8000/path?sth=exampleurl", headers).map(res => res.json()).subscribe(data => this.data = data);
object.sth = this.data;
this.http.post(url, JSON.stringify(YOURSTRING), {headers:{'Content-Type': 'application/json'}})
It should work for request. (Ur first question)
in top of ur component
import { Headers, Http } from "#angular/http";
ur component:
constructor(private http: Http) {}
yourRequest() {
let headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded' })
this.http.post(url, JSON.stringify(YOURSTRING), headers).subscribe(res=>console.log(res));
}
I'm going to update the answer with more complete syntax. Hopefully that can get you something running without an error.
import { Http } from '#angular/http';
import { Component } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
#Component({
selector: 'my-app',
template: `<h1>Hello World</h1>`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
private headers: Headers;
private options: RequestOptions;
constructor(private http: Http) {
this.headers = new Headers({ 'Content-Type': 'application/x-www-form- urlencoded' });
this.options = new RequestOptions({ headers: this.headers });
}
ngOnInit() {
this.doPost().subscribe(response => {
console.log(response);
});
}
doPost() {
return this.http.post("http://localhost:8000/sth", this.options).map(res => res.json());
}
}
Original:
I think what you're missing is the subscribe. Observables won't execute unless you subscribe to them.
this.http.post("http://localhost:8000/", JSON.stringify({ body: 'String' }), {headers:{'Content-Type': 'application/json'}}).subscribe(res=>console.log(res));
Just for the record, it is usually better to put your http calls in a service, not inside the component.
Related
I'm calling REST API from my angular app, I've written below service class in typescript. I want to call different url and pass different headers based on the environment selection.
For example: if environment is dev then userURL value should be http://mydomain-dev.com/users/ and header should be devHttpOptions, similarly for QA - the userURL should be http://mydomain-qa.com/users/ and header should be qaHttpOptions and so on.
I've written below switch case statement, based on environment value, I'm deciding which url and header should be assigned.
But I'm getting below compile time error when I pass this.httpOptions in get method - this.http.get<User[]>(this.userURL, this.httpOptions)
Type 'Observable<HttpEvent<User[]>>' is not assignable to type 'Observable<User[]>'.
Type 'HttpEvent<User[]>' is not assignable to type 'User[]'.
Type 'HttpSentEvent' is missing the following properties from type 'User[]': length, pop, push, concat, and 28 more.ts(
Please find my code below:
UserService.ts
import { Injectable } from "#angular/core";
import { HttpClient } from "#angular/common/http";
import { Observable } from "rxjs";
import { User } from "./user";
import { HttpHeaders } from '#angular/common/http';
#Injectable({ providedIn: 'root' })
export class UserService {
constructor(private http: HttpClient) { }
userURL: any;
httpOptions: any;
devHttpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa('dev-xxxx:yyyy')
})
};
qaHttpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa('qa-xxxx:yyyy')
})
};
prodHttpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa('prod-xxxx:yyyy')
})
};
getUsers(environment): Observable<User[]> {
console.log(environment);
switch (environment) {
case 'dev':
this.userURL = 'http://mydomain-dev.com/users/';
this.httpOptions = this.devHttpOptions;
break;
case 'qa':
this.userURL = 'http://mydomain-qa.com/users/';
this.httpOptions = this.qaHttpOptions;
break;
case 'prod':
this.userURL = 'http://mydomain-prod.com/users/';
this.httpOptions = this.prodHttpOptions;
break;
}
return this.http.get<User[]>(this.userURL, this.httpOptions);
}
}
Could you please help me with this issue. Appreciated your help in advance!
Thanks!
http headers is not found on the httpsOptions variable of type any so you can use it directly this way. You should do something like this:
return this.http.get<User[]>(this.userURL, {
headers: this.httpOptions?.headers
});
You can see all of the overloads for get() here:
https://angular.io/api/common/http/HttpClient#get
It doesn't know that httpOptions is an object so it is using the wrong overload. When you use any it defaults to the first overload that matches get<T> which returns Observable<HttpEvent<T>>. If you declare an object that does not have an observe property on it, it'll use the overload you want, since observe is an optional property on that one, while it is required on the others.
Initialize httpOptions as an object or declare it as an object.
httpOptions = {};
or
httpOptions: Object;
Alternatively you can put observe: 'body' on the options object. That will explicitly select the overload you want.
httpOptions: any;
getUsers(environment) {
...
return this.http.get<User[]>(this.userURL, {
...this.httpOptions,
observe: 'body',
});
}
I want to display the ngx-wheel using api but I'm having trouble displaying the data.
Here my Service :
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class RestServices {
restEndpoint:string = 'https://gorest.co.in/public/v2/users'
constructor(
private httpClient: HttpClient
) { }
async getServiceId() {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
}
return this.httpClient.get<any[]>(this.restEndpoint, httpOptions)
}
Here my Component :
private subscription: Subscription | undefined;
items: any = []
ngOnInit(): void {
this.subscription = this._restService.getServices()
.subscribe((res:any)=>{
let item = res
this.items = item.map((v:any) => ({
text: v.name,
id: v.id,
textFillStyle: "white",
textFontSize: "16"
}));
})
}
ngOnDestroy(): void {
this.subscription?.unsubscribe()
}
Here for html
<ngx-wheel #wheel [width]='350' [height]='350' [spinDuration]='8' [disableSpinOnClick]='true' [items]='items'
[innerRadius]='10' [spinAmount]='10' [textOrientation]='textOrientation' [textAlignment]='textAlignment'
pointerStrokeColor='black' pointerFillColor='white' [idToLandOn]='idToLandOn' (onSpinStart)='before()'
(onSpinComplete)='after()'>
I hope to find the answer here. Thank you
First, you don't need await, async and ,toPromise()... remove them and simply return
return this.httpClient.get<any[]>(this.restEndpoint, httpOptions);
inside your component you should use your constructor only for simple data initialization: if you have to consume a rest api it is a better approach to move that piece of code inside the ngOnInit method:
items: any[] = []
constructor(private restService: RestService){}//dependency injection
ngOnInit(): void {
this.restService.getServiceId().subscribe(response => {
console.log('response success: ', response);
this.items = response; //this may change a little based on your api
console.log('items: ', this.items);
}, errorLog => {
console.log('response error: ', errorLog)
});
}
The above solution is valid, you can enrich it by adding a *ngIf="isLoaded" on your html element and set to true the isLoaded INSIDE subscribe method. but if you prefer you can do the following in the component.ts
items$: Observable<any> = EMPTY;
constructor(private restService: RestService){}//dependency injection
ngOnInit(): void {
this.items$ = this.restService.getServiceId();
}
then, in your html it would change to the following:
<ngx-wheel #wheel *ngIf="items$ | async as items" [width]='350' [height]='350' [spinDuration]='8' [disableSpinOnClick]='true' [items]='items'
[innerRadius]='10' [spinAmount]='10' [textOrientation]='textOrientation' [textAlignment]='textAlignment'
pointerStrokeColor='black' pointerFillColor='white' [idToLandOn]='idToLandOn' (onSpinStart)='before()'
(onSpinComplete)='after()'>
I'm new to Angular and hoping someone can guide me through the process of making a soap call. I can call the endpoint with a Request in SoapUI and it returns the correct Response. Now I'd like to know how to do the same thing in Angular.
The closest one I could find is Answer #3. But it doesn't provide enough context for a beginner.
Here's what I've got so far:
app.component.ts
import { Component } from '#angular/core';
import { SoapService } from './soap.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
title = 'Test of SOAP calls'
name = 'SOAP Prototype';
response: any;
constructor(private soapService: SoapService)
{
soapService.getResponse().subscribe(
res => {
console.log("returned data: ",res);
}
);
}
}
soap.service.ts
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '#angular/common/http';
import { Subject } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
#Injectable()
export class SoapService
{
constructor(private httpClient: HttpClient) { }
getResponse()
{
const myheaders = new HttpHeaders();
myheaders.set('Content-Type','text/xml');
const myparams = new HttpParams();
myparams.set('username', 'me');
myparams.set('acctId','1585');
myparams.set('domain','USR');
myparams.set('active','true');
const response = this.httpClient.post<any>('url-to-soap-service', {headers: myheaders, params: myparams, responseType: 'text'});
console.log(response);
return response;
}
}
Nothing is logged to the console in app.component.ts, nor in soap.service.ts.
I'm see this error in the browser console:
"<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">soap:Bodysoap:Faultsoap:ClientError
reading XMLStreamReader: Unexpected character '{' (code 123) in
prolog; expected '<'\n at [row,col {unknown-source}]:
[1,1]</soap:Fault></soap:Body></soap:Envelope>"
I don't see how there can be an unexpected char when the HttpClient is generating the soap envelope.
What am I doing wrong?
First of all, I am very new to Angular2 (or any other version actually) and I have followed several tutorials to get me started but I'm now in a dead end and I don't know how to proceed.
Here is the background: I am accessing a third party web API through a POST request (I did that in a service) and it returns HTML markup of the control I need to render on my page, so I made a component of it. It works fine (I had to create a custom pipe to work around the DOM sanitization though).
And here's my issue: in the markup I'm receiving from the web API there's JavaScript stuff to initialize the control that is supposed to execute as soon as it is on the page (it does in every other language I used this control in, PHP, Java, JavaScript, ASP.NET, etc) but for some reason, using Angular2 I can see the script in the DOM, properly inserted at the end of the markup but it does not execute so my control does not work.
Here is my component code:
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
import { MyService } from './my.service'
#Component({
selector: 'mycontrol',
template: `<div style="width:1200px; height:1000px;" [innerHtml]="htmlContent | keepHtml"></div>`,
styleUrls: ['app/control-min.css'],
encapsulation: ViewEncapsulation.None
})
export class MyComponent implements OnInit {
htmlContent: any;
constructor(private myService: MyService) {
}
ngOnInit(): void {
this.myService.getControlMarkup().subscribe(
response => this.htmlContent = response["HtmlContent"],
error => this.htmlContent = <any>error
);
}
}
And here is my service code:
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
#Injectable()
export class MyService {
headers: Headers;
options: RequestOptions;
constructor(private http: Http) {
this.headers = new Headers({ 'Content-Type': 'application/json' });
this.options = new RequestOptions({ headers: this.headers });
}
getControlMarkup() {
let controlConfig = {
SessionId: "mySessionId",
ControlId: "MyControl1"
};
let body = JSON.stringify(controlConfig);
return this.http
.post('http://localhost:62968/api/GetControl', body, this.options)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body || {};
}
private handleError(error: any) {
let errMsg = (error.message) ? error.message : error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg);
return Observable.throw(errMsg);
}
}
Any idea how I can make this work?
I've seen that this problem is fairly common across Angular 2, but I haven't seen anything that helps with my particular situation.
Specifically, I'm creating an app that's pulling data from an API (which requires an API key), where the results are specifically in XML format. What I'm trying to do is call the API when a user enters search parameters, have the API return the results, and then eventually display the results on the same screen.
However, I keep encountering the same "Unexpected token <" error, where the source of the error is on the URL of the API itself. I have my suspicion that the problem is stemming from the fact that I'm attempting to return the body as JSON, but I've never experienced this problem before so I was hoping the community could help!
Here's my Service and Component code below:
search-bar.component.ts
import { Component, Output, Input, EventEmitter } from '#angular/core';
import { NgForm } from '#angular/forms';
import { NgModel } from '#angular/forms';
import { Observable } from 'rxjs/Observable';
import { Search } from './search';
import { ZillowSearchService } from './zillow-search.service';
#Component({
moduleId: module.id,
selector: 'search-bar',
templateUrl: `search-bar.component.html`,
styles: [
`input {
width: 50%;
margin-left: 25%;
margin-top: 15%;
color: black;
height: 40px;
}
button {
border-radius: 5px;
margin-top: 5%;
margin-left: 45%;
}
`
]
})
export class SearchBarComponent {
getSearchResults: string;
model = new Search("");
constructor( private zillowSearchService: ZillowSearchService) {}
private sub: any;
public state: string = "" ;
data: string;
onSubmit(){
this.zillowSearchService.searchZillow("New Mexico")
.subscribe(
data => console.log(data),
error => console.log("Error: " + error)
);
}
}
zillow-search.service.ts:
import { Inject, Injectable } from '#angular/core';
import { Http, Headers, Response, Jsonp } from '#angular/http';
import { Observable } from 'rxjs/Rx';
import '../rxjs-operators';
import { AppConfig } from './app-config';
import { Search } from './search';
let api = AppConfig.baseUrls.api;
let url = AppConfig.baseUrls.base;
#Injectable()
export class ZillowSearchService {
public state: string;
constructor ( #Inject(Jsonp) private jsonp: Jsonp) {
//this.http = http;
}
protected results: any;
searchZillow(statevar: any) {
console.log("Before" + statevar);
var queryString = url + `?zws-id=${api}&state=${statevar}&callback=JSONP_CALLBACK`;
return this.jsonp
.get(queryString, new Headers({ "Content-type":
"application/xml", "Accept": "application/xml",
"Access-Control-Allow-Origin": "*" }))
.map((res: Response) => res.json())
//.map(res => console.log("TEST"));
//.map((res) => {
//return
//});;
}
}
For some additional details, looking into the Console and Network, I can see that the "type" is listed as script and the initiator is http.umd.js, where it points me to BrowserJsonp.send (if this helps provider any context at all).
Let me know if you'd like for me to include any additional code snippets, and I really appreciate the help and guidance!
You mentioned the results are in XML format, but I see this code at the bottom of your service:
return this.jsonp
.get(queryString, new Headers({ "Content-type":
"application/xml", "Accept": "application/xml",
"Access-Control-Allow-Origin": "*" }))
.map((res: Response) => res.json())
//.map(res => console.log("TEST"));
//.map((res) => {
//return
//});;
}
I'm not certain that you are able to map the response to json that way -- I think it's actually expecting JSON there from a literal that it would map into a typed object you could use.
So the problem is that you are trying to parse xml as json -- hence the error saying that it can't parse the first "<", as that's not valid json.
You will probably need some sort of xml parser to resolve this -- I would look for a 3rd party library in this case :)
EDIT: To be clear, I think the line:
.map((res: Response) => res.json())
is causing the issue, as it's saying take this input json response and convert it to a usable javascript object -- but it can't parse it, as the response is in XML format.