Retrieve html from server and display with Angular - html

I'm trying to retrieve HTML from a REST service and display it using Angular (4.3). I can watch the service get called and return the correct content. However, the angular component using this never seems to actually receive the content. What have I missed?
Specifically a console.log(html) (in the second code sample below) always outputs null.
I have an angular service that looks like:
#Injectable()
export class SlidesService {
private requestUrl: string;
constructor(
#Inject(AppConfig) private config: AppConfig,
#Inject(HttpClient) private http: HttpClient) {
this.requestUrl = this.config.restRoot + listSlidesUrl;
}
getSlide(deck: string, slide: string): Observable<string> {
const headers: HttpHeaders = new HttpHeaders({'Accept': 'text/html'});
const thisUrl: string = this.requestUrl + '/' + deck + '/' + slide;
return this.http.get<string>(thisUrl, { headers: headers });
}
}
This is used by a component:
export class SlidePreviewComponent implements OnInit {
#Input() slide: string; /* Identifier for the slide */
#Input() deck: string;
slideHtml: string;
constructor(private slideService: SlidesService) {
}
ngOnInit(): void {
this.slideService.getSlide(this.deck, this.slide)
.subscribe(html => this.setSlideHtml(html) );
}
setSlideHtml(html: string) {
this.slideHtml = html;
console.log(html);
}
}

The new HttpClient class expects the get() method to return JSON response. If you expect a text (HTML), it's necessary to specify it in the request options:
this.http.get(thisUrl, { headers: headers, responseType: 'text' });
The special Accept header may be unnecessary then.

Hi can you try this in service
getSlide(deck: string, slide: string){
const thisUrl: string = this.requestUrl + '/' + deck + '/' + slide;
return this.http
.get(url ,{ headers: headers, responseType: 'text' })
.toPromise()
.then(resp => resp.text())
.catch(error=>console.log(error))
}
and your component
ngOnInit(): void {
this.slideService.getSlide(this.deck, this.slide)
.subscribe(html => this.setSlideHtml(html) );
}
setSlideHtml(html) {
this.slideHtml = html;
console.log(html);
}
in your template
<div id="scroll" [innerHTML]="slideHtml"></div>

Related

Get titles from Wikipedia

I am kinda new to Angular.
I am trying to get 4 titles from Wikipedia API, but i can't figure up what's wrong in my code
this is the eample URL for 1 title
example URL = https://en.wikipedia.org/w/api.php?action=query&prop=pageprops&format=json&titles=Wilson_Lumpkin
model
IwikiItem.ts:
export interface IWikiItem {
batchcomplete?: string;
query?: Query;
}
export interface Query {
normalized?: Normalized[];
pages?: Pages;
}
export interface Normalized {
from?: string;
to?: string;
}
export interface Pages {
id?: The4101295;
}
export interface The4101295 {
pageid?: number;
ns?: number;
title?: string;
pageprops?: Pageprops;
}
export interface Pageprops {
defaultsort?: string;
page_image_free?: string;
wikibase_item?: string;
}
Component
private titles = [
'Wilson_Lumpkin',
'Robert Toombs',
'Saxby Chambliss',
'Wyche Fowler',
];
export class HomeComponent implements OnInit {
dataSource: MatTableDataSource<IWikiItem>;
constructor(private srv: SrvService) {
this.titles.forEach((name) => {
this.srv
.getWiki('action=query&prop=pageprops&format=json&titles=' + name)
.subscribe((data) => {
console.log(data.query),
(this.dataSource: new MatTableDataSource<IWikiItem[data]>);
(err) => {
console.log(err);
};
});
});
}
}
service
export class SrvService {
readonly base_url = 'https://en.wikipedia.org/w/api.php?';
getWiki(title: string) {
return this.http.get<IWikiItem>(this.base_url + title);
}
constructor(private http: HttpClient) {}
}
What's wrong here? i am, getting this error in console:
error msg
Edit 1
I am getting an error this.handle eror.
error
I guess Wikipedia APis does not support CORS. So instead of normal http request, you need t make a jsonp request.
For jsonp request you need to import module HttpClientJsonpModule in your application.
After that you can make the request like below.
Reference Link
getWiki(title: string) {
const url = this.base_url + title;
return this.http.jsonp(url, 'callback').pipe(
catchError(this.handleError) // then handle the error
);
}
callback(response) {
console.log("response", response);
}
handleError(error){
console.log(error);
}
Working sample Link

How to get data of YAML file in the Angular 7 array of objects

I know how to get a JSON file and to show it in the array in Angular 7 but I am having a problem with the YAML file I have searched and I really do not know how to get in the array the YAML
For the moment I have tried this but it is coming with errors.
Service
#Injectable({
providedIn: 'root'
})
export class getYamlDataService {
constructor(private http: HttpClient) {
this.getJson().subscribe(data => {
console.log(data);
})
}
public getJson(): Observable<any> {
return this.http.get("./assets/swagger/swagger.yaml");
}
}
Component.ts
constructor(private getYamlData: getYamlDataService) {}
ngOnInit() {
this.getYamlData.getJson().subscribe(data => {
console.log(data);
});
Error
Http failure during parsing for http://localhost:4200/assets/swagger/swagger.yaml
But when I open this localhost then it is showing in browser yaml file.
This is due to your response being parsed as a JSON Object instead of returning a plain string. If you look at the API of HttpClient.get(string) without an options parameter, you will see that the response is observed as a json (found here, 15th overload)
get<T>(url: string, options?: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<T>
You have to specify the return type you want (in this case most likely "text")
#Injectable({
providedIn: 'root'
})
export class getYamlDataService {
constructor(private http: HttpClient) {
this.getJson().subscribe(data => {
console.log(data);
})
}
public getJson(): Observable<any> {
return this.http.get("./assets/swagger/swagger.yaml", {
observe: 'body',
responseType: "text"; // This one here tells HttpClient to parse it as text, not as JSON
});
}
}
If you want to use that yaml as a JavaScript Object, you will have to parse it yourself. Luckily, there are already libararies like yaml.js that you can leverage for this. First, install the libarary npm i --save yamljs and then use it like this:
import {parse} from 'yamljs';
import {map} from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class getYamlDataService {
constructor(private http: HttpClient) {
this.getJson().subscribe(data => {
console.log(data);
})
}
public getJson(): Observable<any> {
return this.http.get("./assets/swagger/swagger.yaml", {
observe: 'body',
responseType: "text" // This one here tells HttpClient to parse it as text, not as JSON
}).pipe(
// Map Yaml to JavaScript Object
map(yamlString => parse(yamlString))
);
}
}
Here is a working StackBlitz showcasing this.
Edit: Added example for parsing the returned string to a JavaScript Object
Edit2: Added StackBlitz example

Angular HTTP GET

I have a server running on "localhost:3000". It displays data as JSON at e.g. "localhost:300/locations".
My "data.service.ts" includes this code:
path: string = 'http://localhost:3000'
constructor(private http: HttpClient) { }
// Locations
getAllLocations(): Observable<Location[]> {
let location = null;
this.http.get(this.path + '/locations')
.map((res => location = res))
.catch((error: any) => Observable.throw(console.log(error)));
return location;
}
In my result.component.ts I'm running this code:
constuctor(private dataservice: DataService) { }
ngOnInit() {
console.info(this.dataservice.getAllLocations());
}
I'm expecting to get as output all Locations as JSON, instead of this the output is "null".
Does anyone have a suggestion on how to make this work properly?
UPDATE:
Also tried this for the HTTP call:
getAllLocations(): Observable<Location[]> {
this.http.get<Location[]>(this.path + '/locations')
.pipe(
tap(items => console.info('fetched items'))
);
}
The output for this code is unfortunately: "Object { _isScalar: false, source: {...}, operator: {...} }"
Did you know that HttpClient#get returns an Observable? You can just return the get method in your method.
Secondly, you can set an interface to the method so that it'll return the JSON as typed.
Lastly, you can use template literals in your API URL.
/**
* Retrieves a list of locations.
* (TODO: Add better documentation here)
*/
getAllLocations(): Observable<Location[]> {
return this.http.get<Location[]>(`${this.path}/locations`);
}
You can then handle this in the actual component that calls this method:
constuctor(private dataservice: DataService) { }
ngOnInit() {
this.dataservice.getAllLocations().subscribe(result => {
console.log(result);
});
}
You have to return Observable from the service:
path: string = 'http://localhost:3000'
constructor(private http: HttpClient) { }
// Locations
getAllLocations(): Observable<Locations[]> {
return this.http.get(this.path + '/locations').pipe(
map((res => location = res)),
catch((error: any) => Observable.throw(console.log(error))));
}
And subscribe to it in the component.
constructor(private dataservice: DataService) { }
ngOnInit() {
this.dataservice.getAllLocations().subscribe(result => {
console.log(result);
})
}

unable to use Angular 6 for reading JSON data on meteo website REST api

I'm trying to read JSON datas from this URL : https://www.prevision-meteo.ch/services/json/lat=46.259lng=5.235
My browser show me a JSON structure and the header contain Access-Control-Allow-Origin *
Unfortunately, there are too much versions of Angular (I'm using v6) and too many differents examples (some only run under 4, some are AngularJS but the title still Angular, etc.)
Could someone give me a simple example with writing the JSON datas on the component view ? thanks.
here is what I'm trying without result for now :
import { Component, OnInit, VERSION } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-get-data-info',
templateUrl: './get-data-info.component.html',
styleUrls: ['./get-data-info.component.css']
})
export class GetDataInfoComponent implements OnInit {
site = 'https://www.prevision-meteo.ch/services/json/';
url = 'lat=46.259lng=5.235';
request = this.site + this.url;
name: String = `Angular version ${VERSION.full}`;
data: any;
constructor(private myHttp: HttpClient) {
this.data = this.test();
console.log('END : le site a été lu par Angular ►' + this.request + 'et renvoit ' + this.data);
}
test() {
console.log('test ► On m\'a appelé ?');
return this.myHttp.get(this.request).subscribe((res: Response) => {
this.data = res.json();
});
}
ngOnInit() {
}
}
Replace this.data = this.test(); with just this.test();and modify test() to be
test() {
console.log('test ► On m\'a appelé ?');
this.myHttp.get(this.request).subscribe(data => {
this.data = data;
});
}
HttpClient by default returns JSON data so
test() {
console.log('test ► On m\'a appelé ?');
this.myHttp.get(this.request).subscribe((res) => {
this.data = res;
});
}
should be good

I am not able access my component's property in the associated template in angular 5

i am calling a http post method and getting the table names from backend, in the template i am trying to display the table names using ngFor. But tablenames aren't visible.
The template is not able to access the tNames property.
I am still at beginner level in angular, so there might be a basic error in the code.
`
#Component({
selector: 'tableList-root',
template: `<ul>
<li *ngFor="let t of tNames">{{t}}</li>
</ul>`
})
export class TableListComponent {
constructor(private http: HttpClient) {}
#Input() sName:string;
#Input() dbName:string;
#Input() name:string;
#Input() passWord:string;
public tNames:string[];
fetchTableNames(sName,dbName,name,passWord)
{
this.fetchTables(sName,dbName,name,passWord).subscribe(res=>{this.tNames=res});//tNames not accesible in the template
}
fetchTables(sName,dbName,name,passWord): Observable<string[]>
{
let data = { "serverName": sName, "databaseName": dbName, "userName": name, "passWord": passWord };
const headers = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) };
let request = "{" + JSON.stringify(data).slice(1, -1) + "}";
return this.http.post('http://localhost/UtilityApp/api/Utility/getTableList',
request,
headers
).map(response=>{return response as string[]})
}`
PFA a snapshot in the below url: -"1: https://i.stack.imgur.com/Vgl2c.png"
#Component({
selector: 'tableList-root',
template: `<ul>
<li *ngFor="let t of tNames">{{t}}</li>
</ul>`
})
export class TableListComponent implements OnInit {
constructor(private http: HttpClient) {}
#Input() sName:string;
#Input() dbName:string;
#Input() name:string;
#Input() passWord:string;
public tNames:string[];
ngOnInit(){
fetchTableNames(sName,dbName,name,passWord)
{
this.fetchTables(sName,dbName,name,passWord).subscribe(res=>{this.tNames=res});//tNames not accesible in the template
}
fetchTables(sName,dbName,name,passWord): Observable<string[]>
{
let data = { "serverName": sName, "databaseName": dbName, "userName": name, "passWord": passWord };
const headers = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) };
let request = "{" + JSON.stringify(data).slice(1, -1) + "}";
return this.http.post('http://localhost/UtilityApp/api/Utility/getTableList',
request,
headers
).map(response=>{return response as string[]})
}`
}
}
// Please import OnInit from angular/core