Displaying simple JSON data from console to HTML in Angular - javascript

I am using openhab for sensor monitoring. But I need to pull/inject the items(things),sensor properties, room configuration through web interface. So, openhab has REST queries which is well documented here - https://docs.openhab.org/configuration/restdocs.html.
I wanted to develop a simple web GUI. (I have no experience in web development before). So, I tried to follow a basic tutorial at angular.io and at - https://medium.com/codingthesmartway-com-blog/angular-4-3-httpclient-accessing-rest-web-services-with-angular-2305b8fd654b.
As shown in the blog, I am able to retrieve a JSON object via Httpclient query till the console but I want to display it in the HTML but I am not finding a wa to do it. So, till now I have the following data at console:
But how to display in the HTML, like what changes do i have to make in app.component.html? If i just try - {{data.login}} , just the string data.login appears in HTML.
I tried searching websites and blogs but they described only ways of how to perform a query and getting till the console. But I needed it at the HTML.
My code: (All are beginner level - basic and default codes)
app.component.ts
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
results = '';
constructor(private http: HttpClient)
{
}
ngOnInit(): void {
this.http.get<UserResponse>('https://api.github.com/users/seeschweiler').subscribe(data => {
console.log("User Login: " + data.login);
console.log("Bio: " + data.bio);
console.log("Company: " + data.company);
});
}
}
app.module.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpClientModule } from '#angular/common/http';
import { AppComponent } from './app.component';
interface UserResponse {
login: string;
bio: string;
company: string;
}
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html:
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<h2>Here are some links to help you start: </h2>
<ul>
<li>
<h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
</li>
<li>
<h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
</li>
<li>
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
</li>
</ul>
Thanks very much for the assistance.

Try this demo
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
title = 'app';
results = {};
constructor(private http: HttpClient)
{
}
ngOnInit(): void {
this.http.get('https://api.github.com/users/seeschweiler').subscribe(data => {
this.results = data;
});
}
}
and in html:
{{results.login}}
You are not able to render {{data.login}} because its a local variable inside subscribe block.

You can edit your html to something like this
<div style="text-align:center">
<pre>
{{ results | json }}
</pre>
<div style="color:red">
{{ results.login }}
<p>and so on</p>
</div>
</div>
and the component's class needs to have a property holding the data. So take this as the class' code
export class AppComponent implements OnInit {
private results: any;
constructor(private http: HttpClient)
{
}
ngOnInit(): void {
this.http.get<any>('https://api.github.com/users/seeschweiler').subscribe(data => {
this.results = data;
});
}
}
Here's a demo

Related

Angular issue with Interpolation and also implementing elements

I have got a problem with String Interpolation.
So I try to make string interpolation according to what the teacher does in the course of Angular
i am doing.
I have a server.component.ts file which is exactly what teacher does in the course.
import { Component } from "#angular/core";
#Component ({
selector: 'app-servers',
templateUrl: './server.component.html'
})
export class ServerComponent {
serverId = 10;
serverStatus = 'offline'
}
And then I try to put it on the server.component.html so it appeared on the browser:
<p>Server with ID {{ serverId }} is {{ serverStatus }}</p>
I have checked multiple times and it seems like I have exactly the same setting that the teacher showed in the course. He has it written in the browser, and I do not.
Here are my other "settings"
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
styles: [`
h1{
color: red
}
`]
})
export class AppComponent {
name = 'Wojtek';
}
**app.component.html
**
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>Hellloo!!!!</h1>
<input type="text">
<p>{{ name }}</p>
<hr>
<app-success-alert></app-success-alert>
<app-warning-alert></app-warning-alert>
</div>
</div>
</div>
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import { ServerComponent } from './server/server.component';
import { ServersComponent } from './servers/servers.component';
import { SuccessAlertComponent } from './success-alert/success-alert.component';
import { WarningAlertComponent } from './warning-alert/warning-alert.component';
#NgModule({
declarations: [
AppComponent,
ServerComponent,
ServersComponent,
SuccessAlertComponent,
WarningAlertComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Also the thing is with implements OnInit in the export class line, in the course it works, however in my VSCode it does not really want to, any ideas?
Please it you may help me I would be really grateful!
I have tried to watch multiple youtube videos, also I came back to the course to rewatch it
It looks like your are missing the server-component in your app-component template. Put <app-servers></app-servers> somewhere in your app-component template.

Getting error trying to pass data to child component in angular

I'm new to angular &I have a component as follows
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor(private http: HttpClient) { }
blogpost;
ngOnInit() {
this.http.get("http://localhost:8080/demo/all").
subscribe(function(data){
this.blogpost=data;
console.log(this.blogpost);
})
}
}
blogpost field contains an array of blogposts obejects
and here is the template associated with component
<div class="row">
<div class="col-sm-6">
</div>
<div class="col-sm-6">
<div class="row">
<div class="col-sm-6"><app-blog-post [title]="blogpost[0].title"></app-blog-post></div>
<div class="col-sm-6">456</div>
</div>
<div class="row">
<div class="col-sm-6">123</div>
<div class="col-sm-6">456</div>
</div>
</div>
</div>
but value passed from this template is not showing in the child component,and I'm getting the error TypeError: Cannot read property '0' of undefined
here is the child component
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-blog-post',
templateUrl: './blog-post.component.html',
styleUrls: ['./blog-post.component.css']
})
export class BlogPostComponent implements OnInit {
ngOnInit() {
}
#Input() title:String="abc";
}
and child template
<div>{{title}}</div>
I couldn't figure out what is wrong. Please somebody help me with this
Move blogpost to out of the constructor then declare it as
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
public blogpost: Array<any> = [];
constructor(private http: HttpClient) { }
ngOnInit() {
this.http.get("http://localhost:8080/demo/all").
subscribe(function(data){
this.blogpost=data;
console.log(this.blogpost);
})
}
}
Don’t forget that http calls are asynchronous so your Post list is not defined before your get request is completed. And so index 0 of undefined is invalid. One solution could be to use ˋ*ngIf="!!blogpost" on app-blog-post component.
A better solution could be using async pipe. Here is a good example : https://medium.com/angular-in-depth/angular-question-rxjs-subscribe-vs-async-pipe-in-component-templates-c956c8c0c794

How to retrieve certain data from URL in Angular 2.0

I have a URL like this one:
https://example.com/?username1=Dr&Organization=Pepper&action=create
I need to display it on my browser inside a text box.
<input type="text" name="varname" value="Dr">
I need to get Dr in my textbox
I'm presuming your url endpoint returns JSON and your attempting to use the returned data to populate your input value.
Firstly import the HttpClientModule in your module dependencies:
import { HttpClientModule } from '#angular/common/http';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Then from within your foo.component.ts you can inject an instance of HttpClient in the constructor.
constructor(private http: HttpClient){
}
Then you can use said HttpClient instance http like so:
this.http.get('https://example.com/?username1=Dr&Organization=Pepper&action=create').subscribe(data => {
console.log(data);
});
}
This can then be put into a property (myProp) which can be referenced like so:
<input *ngIf="myProp" type="text" name="varname" value="myProp">
Note that we use *ngIF to make sure that our property isn't loaded until myProp is not null or undefined.
Main App component - app-root
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
name = null;
constructor(private http: HttpClient){
}
ngOnInit(): void {
this.http.get('https://example.com/?username1=Dr&Organization=Pepper&action=create').subscribe(data => {
// data = result: {name: 'Derek da Doctor'}
this.name = data.result.name;
});
}
}
app.component.html
<input *ngIf="name" type="text" name="varname" value="{{name}}">

angular 4 : Can't bind to 'ngForFor' since it isn't a known property of 'li'

I've just started learning angular 4. This is a simple code that I'm trying to implement in Visual Studio Code, but keep getting this error.
Uncaught Error: Template parse errors:
Can't bind to 'ngForFor' since it isn't a known property of 'li'. ("
</ul>
<ul>
<li [ERROR ->]*ngFor="let hobby for hobbies">{{hobby}}</li>
</ul>"): ng:///AppModule/UserComponent.html#6:6
Property binding ngForFor not used by any directive on an embedded template.
Make sure that the property name is spelled correctly and all directives are
listed in the "#NgModule.declarations".("
</ul>
<ul>
[ERROR ->]<li *ngFor="let hobby for hobbies">{{hobby}}</li>
</ul>"): ng:///AppModule/UserComponent.html#6:2
I tried previous solutions of adding the CommonModule to the app.module file. But it hasn't solved the issue.I cannot figure out what is wrong.
app.component.ts:
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
}
app.module.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { UserComponent } from './components/user/user.component';
import {CommonModule} from '#angular/common';
#NgModule({
declarations: [
AppComponent,
UserComponent
],
imports: [
BrowserModule,CommonModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
user.component.ts:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
name:string;
age:number;
address: Address;
hobbies:string[];
constructor() {
console.log('constructor ran ...');
}
ngOnInit() {
console.log('ngOnInit ran ...');
this.name='Raul';
this.age=22;
this.address= {
street:'abc',
city:'xyz',
country: 'jkl'
}
this.hobbies=['reading','playing','swimming'];
}
}
interface Address{
street:string,
city:string,
country:string
}
user.component.html:
<h1>{{name}}</h1>
<ul>
<li>Age:{{age}}</li>
<li>Address:{{address.street}}, {{address.city}},{{address.country}}</li>
</ul>
<ul>
<li *ngFor="let hobby for hobbies">{{hobby}}</li>
</ul>
should be of instead of for inside the ngFor
ngFor="let hobby of hobbies"

getting ExpressionChangedAfterItHasBeenCheckedError Angular 4

Im aware similar questions exist but none of those have provided me with an answer that works..
Basically I have a site with some services that inject data dynamically
In my app.component.ts I have two headers.. one when your on the home page and one for when your on any other page
app.component.html
<app-header *ngIf="router.url !== '/'"></app-header>
<app-header-home *ngIf="router.url != '/'"></app-header-home>
<router-outlet></router-outlet>
<app-footer></app-footer>
app.component.ts
import { Component } from '#angular/core';
import { Router } from '#angular/router';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'app';
router: string;
constructor(
private _router: Router
) {
this.router = _router.url;
}
}
now I also have a service that dynamically injects the title of the header
headerTitle.service.ts
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
#Injectable()
export class HeaderTitleService {
title = new BehaviorSubject('');
constructor() { }
setTitle(title: any) {
this.title.next(title);
}
}
then In my home component for example I set the title
home.component.ts
import { Component, OnInit, AfterViewInit } from '#angular/core';
import { HeaderTitleService } from '../../services/headerTitle.service';
import { HeaderImageService } from '../../services/headerImage.service';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
constructor(
private headerTitleService: HeaderTitleService,
private headerImageService: HeaderImageService
) { }
ngOnInit() {
}
ngAfterViewInit() {
this.headerTitleService.setTitle(`
We strive to create things
<br> that are engaging, progressive
<br> & above all
<span class="highlight">
<em>innovative.</em>
</span>
`);
}
}
now basically it was all working until I put in the if statements on the two headers
now Im getting this error
Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: ''. Current value: '
We strive to create things
<br> that are engaging, progressive
<br> & above all
<span class="highlight">
<em>innovative.</em>
</span>
'.
not sure how I can fix this.. I tried setting the values in ngAfterViewInit but it did nothing
or does anyone know another way I could accomplish this??
Thanks
You can try using a setTimeOut method instead and set the values
inside of that
setTimeout(this.headerTitleService.setTitle(`
We strive to create things
<br> that are engaging, progressive
<br> & above all
<span class="highlight">
<em>innovative.</em>
</span>
`), 0);
note this is a work around and not a full proff solution to the problem .
To know why this error occurs in Angular change detection you need to know how the change detection works in Angular for this you can refer to this blog by Maxim NgWizard K
I know i fixed this in mine.
here is a great post
everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror
i have forced the change detection
export class AppComponent {
name = 'I am A component';
text = 'A message for the child component';
constructor(private cd: ChangeDetectorRef) {
}
ngAfterViewInit() {
this.cd.detectChanges();
}

Categories