I have created a small program which is used to post the data and get the result back in the server.I have created a button in .html and function works fine.I am getting access log from the server side once I click POST button. But I couldnot display the data. Should I use GET function again or is there any simple way ?
app.component.ts
import {Injectable, Component } from '#angular/core';
import { Http, Response, RequestOptions, Headers} from '#angular/http';
#Component({
selector: 'app-root',
templateUrl:'app.component.html'
})
export class AppComponent {
result;
constructor (private http:Http) {
}
executeHttp() {
var headers = new Headers();
//this.createAuthorizationHeader(headers);
headers.append('Content-Type', 'application/json');
var content = JSON.stringify({
name: 'my name'
});
return this.http.post(
'http://100.000.00.000/webservices/voltage-info-service/server/server.php', content, {
headers: headers
}).map(res => res.json()).subscribe((data)
=> { '<?xml version="1.0" encoding="utf-8"?><lfc:requests><lfc:request><lfc:busID>66</lfc:busID><lfc:timestamp>223456789</lfc:timestamp><lfc:coordinates>'+
'<lfc:LongD>8</lfc:LongD><lfc:LongM>6</lfc:LongM><lfc:LongS>25.599</lfc:LongS><lfc:LatD>51</lfc:LatD><lfc:LatM>33</lfc:LatM><lfc:LatS>23.9898</lfc:LatS>'+
'</lfc:coordinates></lfc:request></lfc:requests>';},
this.result =data;
console.log("data"); },
err => { console.log(err); }
);
}
}
app.component.html
<li>
<button type="submit" (click)="executeHttp()">SOAP request </button>
</li>
So a better approach would be if you make an attribute on the AppComponent, like 'result'.
export class AppComponent {
result;
...
Then in the subscribe next section something like:
.subscribe((data) => {
this.result = data;
})
and then in app.component.html:
<div>{{result}}</div>
Related
I have an IONIC APP with CORDOVA. I Just want to GET a JSON from an URL.
I Created a service call rest.service.ts
rest.service.ts
import { Injectable } from '#angular/core';
import { HTTP } from '#ionic-native/http/ngx';
#Injectable({
providedIn: 'root'
})
export class RestService {
BASE_URL = 'http://whatever.....';
constructor(public http: HTTP) {}
getProjects() {
const URL = this.BASE_URL + 'getProjects';
this.http.get(URL, {}, { 'Content-Type': 'application/json' })
.then(answer => {
return JSON.parse(answer.data);
})
.catch(error => {
console.log(error.status);
console.log(error.error); // error message as string
console.log(error.headers);
});
}
}
Here in this file I can see the info. If I insert something like...
console.log(JSON.parse(answer.data));
I can see the results in JSON just as I Want.
The problem is when I try to use this methods in other files...
otherpage.page.ts
import { Platform } from '#ionic/angular';
import { RestService } from './../rest.service';
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-otherpage',
templateUrl: './otheropage .page.html',
styleUrls: ['./otherpage .page.scss']
})
export class OtherPage implements OnInit {
projects;
constructor(
public platform: Platform,
public rest: RestService,
) {
this.projects = this.rest.getProjects();
console.log(this.projects); // UNDEFINED
}
ngOnInit() { }
}
Here... this.projects... is undefined... ¿What is happening? I tried platform.ready, insert in ngOnInit... nothing works.
You need to modify the service and subscribe this service your page.
BASE_URL = 'http://whatever.....';
getProjects() {
const URL = this.BASE_URL + 'getProjects';
return this.http.get(URL, {}, { 'Content-Type': 'application/json' });
}
Subscribe this service observable in your page.ts file.
this.rest.getProjects().subscribe((answer)=>{
this.projects = JSON.parse(answer.data);
console.log(this.projects); // here you get the json
},error=>{
consoole.log(error)
});
Note:
console.log(this.projects); // UNDEFINED
Because this line executes before the http observable send the response, you need to subscribe that http observable to get the json.
I'm facing a problem with Angular at the moment.
I want to read data from my server API and want to display it with *ngfor in a html document.
I can receive the data from the API, but i can't display it.
I took the example code from the tour of heroes tutorial and changed it:
The data gets through to my angular app. I can console.log it and see it in chrome development console.
I tried to display other data that I get from my api and it is working. You can see the data commented out in heroes.components.ts.
Who can help me with this?
If you want to see some more of the code like imports please tell me. But i guess everything needed imported as there are no error messages, i can get the data from my api and i can display some data (sadly not the data i need).
I tried several ideas to solve this from some other posts, but can't get it working.
Here are some Code Snippets:
This is my hero.service.ts
imports...
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { HttpResponse } from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { catchError, map, tap } from 'rxjs/operators';
import { Hero } from '../model/hero';
import { MessageService } from '../message.service';
import { Response } from '#angular/http/src/static_response';
getHeroes(): Observable<Hero[]> {
console.log("GET HEROES IN HEROES.SERVICE");
return this.http.get<Hero[]>(this.heroesUrl)
.pipe(
tap(Hero => console.log(`fetched heroes: `)),
catchError(this.handleError('getHeroes', []))
);
//I also tried to just use return this.http.get<Hero[]>(this.heroesUrl);
This is my
heroes.components.ts
import { Component, OnInit } from '#angular/core';
import { Hero } from '../../model/hero';
import { HeroService } from '../hero.service';
import { CommonModule } from '#angular/common';
import { Pipe } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { Response } from '#angular/http/src/static_response';
// For use of map
import 'rxjs/Rx';
#Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
heroes: Observable<Hero[]>;
// I tried to display some data
// heroes: any[] = [
// {
// "name": "Douglas Pace"
// }
// ];
constructor(private heroService: HeroService) { }
ngOnInit() {
this.getHeroes();
// undefined
console.log("ONINIT");
console.log(this.heroes);
}
getHeroes(): void {
console.log("GET HEROES IN HEROES.COMPONENT");
this.heroService.getHeroes()
.subscribe(
function(response: Hero[]) {
console.log("RESPONSE IN HEROES COMPONENT");
console.log(this.heroes);
var res = response["data"];
// console.log(res.json());
this.heroes = res;
console.log(this.heroes);
console.log(response["data"]);
},
function(error) {
console.log("Error happened" + error)
},
function() {
console.log("the subscription is completed")
//This shows me the right data.
console.log(this.heroes[5].id);
console.log(this.heroes[5].titel);
console.log(this.heroes[5].name);
console.log(this.heroes[5].vorname);
}
);
}
My html file:
<h2>My Heroes</h2>
<!-- <input type=text ng-model="hero"> -->
// I gave it a try with and without *ngIf="heroes"
<!-- only show the list IF the data is available -->
<div *ngIf="heroes">
<h3>Heroes are available and are displayed</h3>
<li *ngFor="let hero of heroes">
{{hero.name}}
</li>
</div>
<button (click)="button()">
Suchen
</button>
<div *ngIf="heroes">
<table class="heroes">
<tr>
<th>Id</th>
<th>Titel</th>
<th>Nachname</th>
<th>Vorname</th>
</tr>
//I tried async as the data is maybe not available from the
beginning. Also tried async on hero as heroes is created on init
and single heros are added with the function getHeroes();
<tr *ngFor='let hero of heroes | async'>
<a routerLink="/detail/{{hero.id}}">
<td>{{hero.id}}</td>
<td>{{hero.titel}}</td>
<td>{{hero.name}}</td>
<td>{{hero.vorname}}</td>
</a>
<button class="delete" title="delete hero"
(click)="delete(hero)">x</button>
</tr>
</table>
</div>
<pre>{{heroes | json}}</pre>
If got a hero interface. Should be my model. Only Last and First name are needed.
export interface Hero {
id?: string;
name: string;
titel?: string;
vorname: string;
}
The JSON I returned from my API. Online Json formatter says it is valid json.
{"status":"Success","data":
[{"id":"36","name":"Hero","vorname":"Super","titel":"Dr.",},
{"id":"34","name":"Man","Spider":"Ines","titel":""}],
"message":"Retrieved all HEROES"}
this.heroService.getHeroes()
.subscribe(
function(response: Hero[]) { }
Your problem could be here. Your response is an object with (let's say, interface):
interface DataResponse {
success: string;
data?: Hero[];
}
Because you set response: Hero[] and there's no data property in your Hero interface, response["data"] returns null and you'll never get your data. If you run response.data, you'll probably get an error saying data is not defined in Hero etc...
Change to the following:
this.heroService.getHeroes()
.subscribe((response: DataResponse) => {
this.heroes = response["data"];
});
Your code seems to be ok but i see an error in your json format here
"titel":"Dr.",},
try to remove the comma after Dr and give it a try
"titel":"Dr."},
I need to display the data on html that I get from web service. I am able to see the data in a format that I want, but I can't display properly on html. I think -any- in http.get is the problem. I can read data in console without -any- but it works fine with . When it works with it, it still does not print in html properly. Can anyone provide advice on this?
html
<div>{{this.res}}</div>
app.component.ts
import { Component, OnInit } from '#angular/core';
//import { IMovie } from './movie';
import { AppService } from './app.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
res: any[] ;
errorMessage: string;
constructor(private _appService: AppService) { }
ngOnInit(): void { this.getData(); }
getData(): void {
this._appService.getData()
.subscribe(
(res: any []) => this.res = res,
(error: any) => this.errorMessage = <any>error);
}
}
app.service.ts :
Injectable()
export class AppService {
private urlNorth = '';
constructor(private http: HttpClient) { }
getData(): Observable<any> {
const headers = new HttpHeaders();
headers.set('Content-Type', 'text/sml');
headers.set('Accept', 'text/xml');
headers.set('Content-Type', 'text/xml');
return this.http.get<any>(this.urlNorth,{responseType:'text', headers: headers})
.do(data => {
// console.log(data)
var dataParsed = data.replace('<string xmlns="service">', '').replace('</string>', '').replace(/</g, '<').replace(/>/g, '>');
// console.log(dataParsed);
parseString(dataParsed, (err, res) => {
if (err) {
return console.dir('invalid XML');
}
else {
console.log(res);
console.log(res.NewDataSet.Table[0].DataPointName[0]);
}
})
})
.catch(this.handleError);
}
**data in console w/o any **
{{this.res}} in html
I'm pretty sure you don't have to put any at this line in app.service.ts
return this.http.get<any>(this.urlNorth,{responseType:'text', headers: headers})
because get method expects 0 type arguments.
Type any is not the problem. It's just TypeScript annotation to organise your code. The problem is you are refering to the res in inline template as this.res, but you should just res. However it won't work as you think. Looking at your data structure You will have to iterate throught this data due to Table is an array. Additionaly I Highly suggest to always represnt your data as class
export class Apps {
public Table: Array<any>; //here should be another type instead of "any"
/* rest of data if any */
}
Back to your question you should have in your html file <div>{{res}}</div> but that's just print your object as string if I good remember. So to properly access your data you should iterate through table using *ngFor
<div *ngFor="let el of res.NewDataSet.Table">
<span>{{el.BackColor}}</span>
<!-- all other data -->
</div>
It looks as though the data is coming back. I'll answer your initial question first (since you added a few issues in comments):
My guess is when you get data back, it's not showing because it's HTML, and angular doesn't like injecting html.
Add this to your TS:
import { DomSanitizer, SafeHtml } from '#angular/platform-browser';
res[]: safeHTML;
And change your html to this:
<div [innerHTML]="res"></div>
As mentioned in a previous answer, this is a solution for a single return of res, not an array of different htmls. If it's an array, you'll have to handle it accordingly. for instance:
<ng-container *ngFor="let r of res">
<div [innerHTML]="r">
</ng-container>
I need help in displaying the output of subscribe from an api in Angular 4. How can i do this since I wrote data.data.data but it says property data doesnt exist on type object. How would i output it in the browser? Here's my code below and the api picture below
import { Component, OnInit } from '#angular/core';
import { NewsService } from '../news.service';
#Component({
selector: 'app-news-list',
templateUrl: './news-list.component.html',
styleUrls: ['./news-list.component.css']
})
export class NewsListComponent implements OnInit {
constructor(private newsService: NewsService) { }
ngOnInit() {
this.newsService.getNews()
.subscribe(
data => {
alert("News Success");
console.log(data);
},
error => {
alert("ERROR");
});
}
}
create a property in component
myData: any[] = [];
and in your subscriber function
import { Component, OnInit } from '#angular/core';
import { NewsService } from '../news.service';
#Component({
selector: 'app-news-list',
templateUrl: './news-list.component.html',
styleUrls: ['./news-list.component.css']
})
export class NewsListComponent implements OnInit {
constructor(private newsService: NewsService) { }
ngOnInit() {
this.newsService.getNews()
.subscribe(
(res: any) => {
alert("News Success");
this.myData = res.data;
// Where you find the array res.data or res.data.data
console.log('res is ', res.data);
},
error => {
alert("ERROR");
});
}
}
and in your template
1) option to view JSON
<pre>{{myData | json}}</pre>
2) option to loop if you got the array
<div *ngFor="let d of myData">
{{d}}
</div>
Your data is type of array,
Create a variable of type any
myData : any;
and assign the data to myData,
this.newsService
.getNews()
.subscribe(
data => {
this.myData = data.data;
},
error => {
alert("ERROR");
}
);
you can use ngFor to iterate over array and display in the HTML
<li *ngFor="let item of myData">
{{item}}
</li>
You need to do it like this
ngOnInit() {
this.newsService.getNews()
.subscribe(
data => {
data = data.json();
console.log(data.data);
},
error => {
alert("ERROR");
});
}
the data.json() part is important, it converts the response into proper json so can access its data.
Now you can assign it to instance variable like this
this.myArrayData = data.data
inside your subscribe() method
Then in your template
<div *ngFor="let data of myArrayData">
<!-- do whatever with the data properties -->
</div>
So I figuring out my way around Angular. Just started with a OpenWeather API based application using a simple GET method.
So here is my app.component.ts:
import { Component } from '#angular/core';
import { WeatherService } from './weather.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [WeatherService]
})
export class AppComponent {
title = 'Ng-Weather';
cityName: string;
constructor(private weather: WeatherService) { }
search() {
this.weather.getWeatherbyName(this.cityName);
}
}
As you can guess, the cityName variable is two way binded. The search() function is invoked onclick of a button and the data is passed to the weatherservice. The contents of weather service is:
import { Injectable } from '#angular/core';
import { Http, Response, URLSearchParams } from '#angular/http';
import { Observable } from 'rxjs';
import { Weather } from './weather';
#Injectable()
export class WeatherService {
APIurl = "http://api.openweathermap.org/data/2.5/weather";
Appid = "xxx";
constructor(private Http: Http) { }
getWeatherbyName(name: string): Observable<any> {
let myParams = new URLSearchParams();
myParams.append('q', name);
myParams.append('appid', this.Appid);
// actual http request should look like this: http://api.openweathermap.org/data/2.5/weather?appid=xxx&q=Chennai
return this.Http.get(this.APIurl, { search: myParams})
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
console.log(res.json());
let body = res.json();
return body.data;
}
private handleError(error: Response | any) {
console.error(error.message || error);
return Observable.throw(error.message || error);
}
}
But I get no error in my console or during the compile process. What is being done wrong? Also, how can I map the JSON I get to my class and give back that instance to the app.component?
Following is my class:
export class Weather {
city: String;
max_temp: String;
min_temp: String;
description: String;
}
And this is a sample JSON I receive:
{
"coord":{
"lon":80.28,
"lat":13.09
},
"weather":[
{
"id":803,
"main":"Clouds",
"description":"broken clouds",
"icon":"04n"
}
],
"base":"stations",
"main":{
"temp":304.15,
"pressure":1008,
"humidity":79,
"temp_min":304.15,
"temp_max":304.15
},
"visibility":6000,
"wind":{
"speed":3.1,
"deg":160
},
"clouds":{
"all":75
},
"dt":1504629000,
"sys":{
"type":1,
"id":7834,
"message":0.0029,
"country":"IN",
"sunrise":1504571272,
"sunset":1504615599
},
"id":1264527,
"name":"Chennai",
"cod":200
}
As you can see all I need is some data from the JSON and not the whole thing.
Your main problem here is that you are not subscribing to the observable that is being produced by your getWeatherbyName function. Observables returned by Http are cold:
Cold observables start running upon subscription, i.e., the observable sequence only starts pushing values to the observers when Subscribe is called. (…) This is different from hot observables such as mouse move events or stock tickers which are already producing values even before a subscription is active.
In order to subscribe to this observable, you can simply update your search function to the following:
search() {
this.weather.getWeatherbyName(this.cityName)
.subscribe();
}
This is by no means the complete solution to your problem - You will want to do something in the subscription, such as assign the information received to properties of your component so that they can be rendered in the UI.
You appear to have other issues in your linked project, but I suggest you ask separate questions on Stack Overflow if needed, or even better, your favorite search engine should be able to help.
Try passing a RequestOptions object to the http get instead:
import { RequestOptions } from '#angular/http';
getWeatherbyName(name: string): Observable<any> {
let myParams = new URLSearchParams();
myParams.append('q', name);
myParams.append('appid', this.Appid);
let options = new RequestOptions({ search: myParams}); //<----- NEW
// actual http request should look like this: http://api.openweathermap.org/data/2.5/weather?appid=xxx&q=Chennai
return this.Http.get(this.APIurl, options) //<<----- NEW
.map(this.extractData)
.catch(this.handleError);
}