Angular2 HTTP TypeScript Json - json

I have one locally stored "region.json" file like this:
{
"regionId":1,
"region":"CAN"
},
{
"regionId":2,
"region":"CEN"
}
I have "enviroment-app.component.ts" file which like this :
import {Component, View, CORE_DIRECTIVES, FORM_DIRECTIVES} from "angular2/core";
import {HTTPTestService} from "./http-test.service";
#Component({
selector: 'my-app'
})
#View({
template: `
<table>
<thead>
<th>Region Id</th>
<th>Region</th>
</thead>
<tbody>
<tr *ngFor="#item of myData">
<td>{{item.regionId}}</td>
<td>{{item.Region}}</td>
</tr>
</tbody>
</table>`
})
export class AppComponent {
myData:any;
}
and I have "http-test.service.ts" file which look like :
import {Injectable} from "angular2/core";
import {Http} from "angular2/http";
import 'rxjs/add/operator/map';
import {Headers} from "angular2/http";
import {AppComponent} from "./environment_app.component";
#Injectable()
export class HTTPTestService{
constructor (private _http: Http){}
this.myData = {region:[]};
get("./region.json") {
return this._http.get("./region.json", { headers: headers })
.map(res => res.json())
.subscribe
(
data => {
this.myData = data;
});
}
}
In the Front-End, I am only able to print the header as
I want to fetch all the json data
What I am doing wrong??
Please, Any help appreciated,
Thanks in advance.

The response of the json goes in a variable named myData. This variable is is a member of the service, and not your AppComponent class. However,
*ngFor="#item of myData"
In the above *ngFor, this myData variable is a part of your AppComponent class which was never filled.
Do this:
Make a function, as you did in your service that returns json data after reading the file.
Return that data back to AppComponent.
Assign that to myData in AppComponent.

Related

Display specific data in a table

I have an angular project where I have a table I am populating from an api.
In the table there is a column status with three values: 1- Open, 2- Released, 3- Rejected.
displayed with,
<td>{{working_period.status}}</td>
Here's pic of the table
Image
What I want is a pipe to display only one status. E.g Only 1- open
How can I go about creating such a pipe, and is it the best solution?
I am newbie in ng7. In case of clarification let me know...please forgive my grammar.
Edit
my dashboard.component.html
<table class="table">
<thead><th>Mitarbeiter</th><th>Einsatz</th><th>Eingangsdatum</th><th>Zeitraum</th><th>Status</th></thead>
<tr *ngFor="let working_period of customers"> ...... <td>{{working_period.status}}</td></tr>
</table>
My dashboard.component.ts
import {Component, AfterViewInit, OnInit, OnDestroy, ViewChild} from '#angular/core';
import { NgbProgressbarConfig } from '#ng-bootstrap/ng-bootstrap';
import {pipe, of, Subscription} from 'rxjs';
import { first } from 'rxjs/operators';
import { ActivityReportsService } from '../../services/activity-reports.service';
import { CustomerLoginService } from '../../services/customer-login.service';
import {Customer, CustomerResponce} from '../../_models/customer';
#Component({
templateUrl: './dashboard1.component.html',
styleUrls: ['./dashboard1.component.css']
})
export class Dashboard1Component implements OnInit, OnDestroy {
currentUser: Customer;
currentUserSubscription: Subscription;
customers: Customer[] = [];
constructor(
private customerloginservice: CustomerLoginService,
private activityreportservice: ActivityReportsService
) {
this.currentUserSubscription = this.customerloginservice.currentUser.subscribe(customer => {
this.currentUser = customer;
});
}
ngOnInit() {
this.loadAllReports();
}
ngOnDestroy() {
this.currentUserSubscription.unsubscribe();
}
private loadAllReports() {
this.activityreportservice.getAll().subscribe((customers: CustomerResponce) => {
console.log(customers);
this.customers = customers.working_periods;
});
}
}
Try this (SearchPipe.pipe.ts)
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'searchFilter'
})
// Pipe to implement a search filter basd on input
export class SearchPipe implements PipeTransform {
transform(items: any[], searchTerm: string): any[] {
if (!items) { return []; }
return items.filter((val) => {
return val.status === searchTerm;
});
}
}
in HTML:
<table class="table">
<thead>
<th>Mitarbeiter</th>
<th>Einsatz</th>
<th>Eingangsdatum</th>
<th>Zeitraum</th>
<th>Status</th>
</thead>
<tr *ngFor="let working_period of customers | searchFilter:'open'"> ......
<td>{{working_period.status}}</td>
</tr>
</table>
Please create 1 function like FilterStatusData(filterstatus) which called after api get response.
In FilterStatusData modify data using loop.
You can fix it without using a pipe (Dashboard1Component)
this.customers = customers.working_periods.filter(res=>res.status==='open');

Angular5 *ngfor not working, but there is no error

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."},

How to capture and display data from Observable?

I have a component named 'customer.component.ts'.
In this component's view there is a button called 'Search'.
What I I am doing is calling a web api method on this 'Search' button click which brings the data from sql db.
For this, I have a customer.service.ts file in which I wrote the below code -
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import { Observable } from 'rxjs';
import "rxjs/add/operator/map";
import 'rxjs/add/operator/toPromise';
import { Customer, CustomerContact, CustomerHeaderAndContactsResponse, CustomerSearchRequestObjectClass, CustomerHeaderAndContactsResponse_Read } from '../models/customer';
#Injectable()
export class CustomerService {
constructor(private _http: Http) {
}
baseUrl: string = 'http://localhost/SampleApi/api/Customer/';
searchCustomers(custReqObj: CustomerSearchRequestObjectClass): observable<CustomerHeaderAndContactsResponse_Read> {
let headers = new Headers();
headers.append('Content-Type', 'application/json; charset=utf-8');
return this._http.post((this.baseUrl + 'search-customer'), JSON.stringify(custReqObj), { headers: headers }).map(res => res.json());
}
}
my customer.component.ts has the search click function -
import { Component, OnInit } from '#angular/core';
import { strictEqual } from 'assert';
import { ChangeDetectorRef } from '#angular/core';
import { stringify } from '#angular/core/src/facade/lang';
import { Customer, CustomerContact, CustomerHeaderAndContactsResponse_Read } from '../models/customer';
import { Observable } from 'rxjs/Observable';
import { CustomerService } from '../services/customer.service';
import { ChangeDetectionStrategy } from '#angular/core/src/change_detection/constants';
import { forEach } from '#angular/router/src/utils/collection';
import { AsyncPipe } from '#angular/common';
import { error } from 'util';
import { parse } from 'path';
import { Subscriber } from 'rxjs/Subscriber';
declare var $: any;
#Component({
selector: 'customer',
templateUrl: 'app/customer/views/customer.component.html',
})
export class CustomerComponent implements OnInit {
constructor(private changeDetectorRef: ChangeDetectorRef, private _custSvc: CustomerService) {
}
ngOnInit() {}
customerSearch: CustomerHeaderAndContactsResponse_Read = new CustomerHeaderAndContactsResponse_Read();
onCustomerSearchClick(): void {
this._custSvc.searchCustomers(this.custSearchReqObj).subscribe(
data => {
this.customerSearch = data;
},
err => console.log(err, 'error has occurred'),
() => console.log(this.customerSearch)
);
console.log(this.customerSearch);
}
And below is my model class -
export class CustomerHeaderAndContactsResponse_Read
{
custHeader:Customer[];
custContact:CustomerContact[];
}
Both Customer and CustomerContact classes contain some properties.
And finally here is my template where I am trying to iterate through the object the table rows simply don't display any data. I have used async (AsyncPipe) also but not helping much.
<tr *ngFor="let custItem of customerSearch.custHeader | async; let rowIndex = index">
<td>
<a (click)="onCustomerItemDetailsClick(custItem.acCustomerName, rowIndex)" class="btn">{{custItem.acCustomerName}}</a>
</td>
<td>{{custItem.acCountryId}}</td>
<td>{{custItem.acAreaId}}</td>
<td>{{custItem.acTel}}</td>
<td>{{custItem.acFax}}</td>
<td>{{custItem.acSalesContact}}</td>
<td>
<a (click)="onCustomerContactItemDeleteClick(rowIndex, 'manage-customer')" class="btn" id="btnIconDelete">
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
</tr>
Please help as I am not unable to understand what/where I am doing mistake.
Do let me know if more information is required.
Thanks in advance!
nitinthombre1991#gmail.com
EDIT -
Tried with BehaviorSubject approach, but now getting an erro like below -
Observable error
The async pipe is used to bind observables directly to the template. So here's what you can do:
data$: Observable<CustomerHeaderAndContactsResponse_Read>;
search$ = new BehaviourSubject<boolean>(true);
ngOnInit() {
this.data$ = this.search$.switchMap(searchObj => this._custSvc.search...(...));
}
onCustomerSearchClick() {
this.search$.next(true);
}
And the template looks like this
<tr *ngFor="let item of data$ | async>...</tr>
So now every time your search is clicked, it will send a call to the service and the async pipe is taking care of displaying the data in the template

put the response of a service inside of a string variable with typescript

i'm working on an angular 4 project and i made a service to get a json from a url, the service.ts looks like this:
import {Injectable} from '#angular/core';
import {Http , Response} from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class EventsService{
constructor(private http:Http){
}
private url: string = "http://urlofmyjson/events";
getEvents() {
return (
this.http.get(this.url).map((response: Response) => response.json())
)
}
}
the content of that json looks like this:
{
"events":[
{
"title":"event1"
"location":"location1"
"date":"date1"
},
{
"title":"event2"
"location":"location2"
"date":"date2"
},
{
"title":"event3"
"location":"location3"
"date":"date3"
},
]
}
and in my component i have this:
import { Component, OnInit } from '#angular/core';
import {EventsService} from './conciertos.service';
#Component({
selector: 'app-events',
templateUrl: './events.component.html',
styleUrls: ['./events.component.scss']
})
export class EventsComponent implements OnInit {
constructor(private EventsService: ConciertosService) { }
events = []:
ngOnInit() {
this.EventsService.getEvents().subscribe( ResponseEvents => this.events=ResponseEvents);
}
}
and then i want to iterate each event of the json with an *ngFor, but as the json retrieves an object with an array inside of it that contains the events objects, i can't iterate it because it throws an error.
how can i put the response of the service inside a string type variable to call and iterate it with *ngFor?

angular2 how to get data by JSON and render them in html

I trying to render JSON data,
i do as follows...
#Component({
selector:'free-ip',
templateUrl:'./freeip.component.html'
})
export class FreeIpComponent implements OnInit{
getData:string[];
constructor(private http: FreeIpService){}
getFreeIp(){
this.http.getData()
.subscribe(
data => this.getData
);
}
ngOnInit(){
this.getFreeIp();
}
}
My JSON format...
[{"name":"1(К2)","ipange":"85.143.77.64/26","count":14},
{"name":"1(К2)","ipange":"109.123.184.128/26","count":31},
{"name":" 7","ipange":"109.123.188.128/25","count":60}]
Please help me, how to render data to html?
Thank you.
There is a simpler way render in HTML using the built-in json pipe:
<pre>{{getData | json}}</pre>
Try this:-
freeIpService.ts file:-
import { Injectable } from '#angular/core';
import { Http, URLSearchParams} from '#angular/http';
export class FreeIpService {
constructor(private http: Http) { }
getFreeIp(){
this.http.get('src/assets/data/freeId.json').map(response => response.json()
}
}
FreeIpComponent.ts file:-
import { Component, OnInit } from '#angular/core';
import { FreeIpService } from './freeIpService';
export class FreeIpComponent implements OnInit{
getData:any;
constructor(private FreeIpService: FreeIpService){}
ngOnInit(){
this.FreeIpService.getFreeIp().subscribe(response => { this.getData = response}, err => console.log(err), ()=> console.log(this.getData));
}
Create service file and paste the service.ts code and create a component and paste component.ts code. In assets folder create data folder and in data folder create json file freeId.json file and paste json code in this file.
<tr *ngFor="let item of getData">
<td>{{item.name}}</td>
<td>{{item.ipange}}</td>
<td>{{item.count}}></td>
this is that i wanted)
thank all for your help
You should serialize or deserialize your data when it is responsed
The first, this your http service
get(uri: string) {
return this._http.get("your uri", { headers: "your headers"}).map(this.extractData);
}
private extractData(response: Response) {
let data = response.json();
return data || {}
}
The second, this is function implement in component
getAll() {
this._httpProviderService.get("/api/product_category/GET/categories")
.subscribe(result => {
this.productCategories = result;
});
}
And the last, this is html
<tr *ngFor="let item of productCategories;let rowIndex=index">
<td class="a-center ">
<input type="checkbox" class="" name="table_records">
</td>
<td class="">{{rowIndex+1}}</td>
<td class="">{{item.ID}}</td>
<td class="">{{item.Name}}</td>
<td class="">{{item.Description}}</td>
<td class="">{{item.Status}}</td>
</tr>