What is dispose of null in Angular 4 - json

I am getting "what is dispose of null" when load the page.
I am to get list of data but unable to show those record in view.
Here i added code snippet to understand my requirement
Angular JS Service File
import { Injectable } from '#angular/core';
import { Http, Headers, Response } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
#Injectable()
export class PostsService {
data: any = null;
totalDocs: number;
url: any = 'http://localhost:3000/services/';
constructor(private _http: Http) { }
public getPosts() {
return this._http.get(this.url + 'posts')
.map((res: Response) => res.json());
}
}
//End Angular JS Web service*
Node JS code to get data from MongoDB
import { default as Category} from "../models/Category";
import { default as Post} from "../models/Post";
import { Request, Response, NextFunction } from "express";
export let getPostsAPI = (req: Request, res: Response, next: NextFunction) => {
const post: any = req.body;
const cond: any = {};
if (!this.empty(post.kword)) {
*//$text is full text index*
cond.$text = {$search : post.kword};
}
if (!this.empty(post.location)) {
cond.city = {$regex: new RegExp("^" + post.location, "i") };
}
*Counting total number of records and
Here Post is reference of collection, its working fine and generating data as i given bottom of this post.*
Post.count(cond).then(totalDocs => {
Post.find(cond).sort({created_at: -1}).then(result => {
const results = {data: result, totalDocs: totalDocs};
console.log(results);
res.end("" + JSON.stringify(results));
});
});
};
End node JS Code
Angular JS home.component.ts where i am calling web serive to render data in angular view
export class HomeComponent implements OnInit {
results: any = {};
model: any = {};
constructor(private posts: PostsService) {
posts.getPosts().subscribe(res => {
console.log(res.totalDocs); // Showing number of records in console.
this.results = res.data; // this is throwing error.
*//Error is: TypeError: Cannot read property 'dispose' of null*
});
this.model.kword = '';
this.model.location = '';
}
ngOnInit() {
}
}
Template Code
<div class="container">
<app-filter [result]=value (clicked)="searchJob($event)"></app-filter>
<!-- /.row -->
<div class="row" >
<div class="col-sm-10 my-10" *ngFor="let post of results | async">
<div class="card">
<div class="card-body">
<h3 class="mt-1"><a [routerLink]="['/job', post.company, post.title, post._id]">{{ post.title }}</a></h3>
<p class="mt-1" *ngIf="post.company"><span class="badge badge-primary">{{post.company}}</span></p>
<p class="mt-1" *ngIf="post.salary_min">Salary up to: ₹{{post.salary_min}} - ₹{{post.salary_max}}</p>
<p class="mt-1" *ngIf="post.city || post.state">Location: {{post.city}}, <span *ngIf="post.state">{{post.state}}</span></p>
<p class="mt-1" *ngIf="post.description">{{post.description | slice:0:150}}[...]</p>
</div>
</div>
</div>
</div>
<!-- /.row -->
</div>
End Template
JSON DATA WHICH COMING FROM API
{
"data":
[
{
"title":"test title",
"description":"test description"
}
],
"totalRecords":2
}
i attached a screenshot of error.

The async pipe subscribes to an observable for you, so it needs to be fed an observable, you're feeding it the resulting value of an observable, which is why you're seeing this error.
Do it like this instead:
results: Observable<any>;
model: any = {};
constructor(private posts: PostsService) {
this.results = posts.getPosts().map(res => res.data);
this.model.kword = '';
this.model.location = '';
}
Now you're setting the "results" value to the actual observable, and letting async handle the subscription part.

Related

Uploading multiple images using angular and send them to api

im using angular as front-end and trying to upload 2 images and then send them as a string to OCR API,
here is my code
let reader:FileReader = new FileReader();
let image = new Image();
var file;
for (var i = 0; i < imgFile.target.files.length; i++){
file = imgFile.target.files[i]
reader.onload = (e: any) => {
image.src = e.target.result;
image.onload = rs => {
//console.log(reader.result);
this.fileString = image.src;
};
};
reader.readAsDataURL(file)
}
the problem is I cant send the files to the API , as I don't know how to get the image data as a string to send them together
what can I do?
Plenty of examples, but you need an upload service with the correct Backend URL to the API, this one can do any file type. Just filter out the file type you dont want in the upload function
POST /upload Upload a file
GET /files Get a list of files
GET /files/[filename] Download a file
src/app/upload.service.ts
import { Injectable } from '#angular/core';
import { HttpClient, HttpRequest, HttpEvent } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class UploadService {
private serverUrl = 'http://localhost:8080';
constructor(private httpClient: HttpClient) { }
upload(file: File): Observable<HttpEvent<any>> {
const formData: FormData = new FormData();
formData.append('file', file);
const request = new HttpRequest('POST', `${this.serverUrl}/upload`, formData, {
reportProgress: true,
responseType: 'json'
});
return this.httpClient.request(request);
}
getFiles(): Observable<any> {
return this.httpClient.get(`${this.serverUrl}/files`);
}
}
Create and MultiImageUploadComponent.ts
import { Component, OnInit } from '#angular/core';
import { UploadService } from 'src/app/upload.service';
import { HttpEventType, HttpResponse } from '#angular/common/http';
import { Observable } from 'rxjs';
export class UploadComponent implements OnInit {
selectedFiles: FileList;
progressInfos = [];
message = '';
fileInfos: Observable<any>;
constructor(private uploadService: UploadService) { }
}
ngOnInit(): void {
this.fileInfos = this.uploadService.getFiles();
}
selectFiles(e): void {
this.progressInfos = [];
this.selectedFiles = e.target.files;
}
uploadFiles(): void {
this.message = '';
for (let i = 0; i < this.selectedFiles.length; i++) {
this.upload(i, this.selectedFiles[i]);
}
}
upload(idx, file): void {
this.progressInfos[idx] = { value: 0, fileName: file.name };
this.uploadService.upload(file).subscribe(
event => {
if (event.type === HttpEventType.UploadProgress) {
this.progressInfos[idx].value = Math.round(100 * event.loaded / event.total);
} else if (event instanceof HttpResponse) {
this.fileInfos = this.uploadService.getFiles();
}
},
err => {
this.progressInfos[idx].value = 0;
this.message = 'Could not upload the file:' + file.name;
});
}
your HTML template
<div *ngFor="let progressInfo of progressInfos" class="mb-2">
<span>{{ progressInfo.fileName }}</span>
<div class="progress">
<div
class="progress-bar progress-bar-info progress-bar-striped"
role="progressbar"
attr.aria-valuenow="{{ progressInfo.value }}"
aria-valuemin="0"
aria-valuemax="100"
[ngStyle]="{ width: progressInfo.value + '%' }"
>
{{ progressInfo.value }}%
</div>
</div>
</div>
<label class="btn btn-default">
<input type="file" multiple (change)="selectFiles($event)" />
</label>
<button
class="btn btn-success"
[disabled]="!selectedFiles"
(click)="uploadFiles()">
Upload
</button>
<div class="alert alert-light" role="alert">{{ message }}</div>
<div class="card">
<div class="card-header">List of Files</div>
<ul
class="list-group list-group-flush"
*ngFor="let file of fileInfos | async"
>
<li class="list-group-item">
{{ file.name }}
</li>
</ul>
</div>
You can call it like so from your app, where <app-upload> is your directive/component above
<h1>{{ title }}</h1>
<div class="container">
<app-upload></app-upload>
</div>
Make sure the OCR API is wired up to the services to invoke & POST

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

POST data in server - angular 4

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>

Filter the data from the return of HTTP Call - Angular

I am creating a project which uses a HTTP get from a web service and returns an array of projects, with ID, name, description etc.
Previously, before I created my filter, the get returned a list of 60 elements using an ngFor in the HTML file:
There is many projects within this web service but I am only concerned with 9 of them the rest are irrelevant.
My code was working when I had created my own observable object with manual data: in my project.service.http.ts class:
data: Project[] = [
{
id:...,
name:...
etc
},
and then in the fetchProjects Method:
fetchProjects(): Observable<Project[]> {
return Observable.of(this.data);
}
Because I want the observable object to be the data from my http get, this method is void. I tried to implement the observable being returned as the data from the web service, but I get the error below in my console when running.
Any help on this would be appreciated.
core.es5.js:1020 ERROR TypeError: response.filter is not a function
at SafeSubscriber._next (project.viewer.component.ts:36)
at SafeSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:238)
at SafeSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.next (Subscriber.js:185)
at Subscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber._next (Subscriber.js:125)
at Subscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at CatchSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber._next (Subscriber.js:125)
at CatchSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at MapSubscriber.webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next (map.js:83)
at MapSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at XMLHttpRequest.onLoad (http.es5.js:1226)
My Code:
project.service.http.ts:
#Injectable()
export class ProjectServiceHttp extends ProjectService {
//variables
baseUrl = "";
static projectIds: string[] = ["","","","","",""
,"", "",""];
//constructor
constructor(private http: Http) {
super();
}
//methods
fetchProjects(): Observable<Project[]>{
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({headers: headers});
return this.http.get(this.baseUrl, options)
.map((response: Response) =>
{
let result = response.json();
return Observable.of(result);
})
.catch(this.handleError);
}
}
project.viewer.component.ts:
#Component({
selector: 'project-viewer',
templateUrl: './project-viewer.html',
styleUrls: ['./project-viewer.css']
})
export class ProjectViewerComponent {
name = 'ProjectViewerComponent';
projects: Project[] = [];
static projectIds: string[] = ["",""
,"","","",""
,"", "",""];
errorMessage = "";
stateValid = true;
constructor(private service: ProjectService) {
this.service.fetchProjects().subscribe(response => {
this.projects = response.filter(elements => {
return ProjectViewerComponent.projectIds.includes(elements.id);
});
})
}
private fetchProjects() {
this.service
.fetchProjects()
.subscribe(response =>{
this.projects = response['project']
.filter(project => { return ['...', '','','','','...'
,'','',''].indexOf(project.id) !== -1})
console.log(response);
console.log(this.projects);
},
errors=>{
console.log(errors);
});
}
}
project-viewer.html:
<h3>Projects </h3>
<div >
<ul class= "grid grid-pad">
<a *ngFor="let project of projects" class="col-1-4">
<li class ="module project" >
<h4 tabindex ="0">{{project.name}}</h4>
</li>
</a>
</ul>
</div>
They are multiple error in your project. First of all in your service you are not using correctly the map operator you should do:
//methods
fetchProjects(): Observable<Project[]>{
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({headers: headers});
return this.http.get(this.baseUrl, options)
.map(response => response.json())
}
Then in the component you subscribe to the service then you try to do the filtering. You can do that before subscribe like this:
private fetchProjects() {
const filterProject = ['TotalMobileAnalyseInsights', 'TotalMobileMendel','TotalMobileSlam','TotalMobileServer','TotalMobileWedAdmin','TotalMobileForAndroid'
,'TotalMobileForWindows','TotalMobileForWindowsUniversal','TotalMobileForIOS'];
this.service.fetchProjects()
// convert each element of the array into a single observable
.flatMap(projects => ArrayObservable.create(projects))
// filter project
.filter(project => filterProject.indexOf(project.id) !== -1)
.toArray()
// subscribe and do something with the project
.subscribe(projects => console.log(projects));
}
Here is a quick running example https://plnkr.co/edit/3nzr3CFhV2y0iu3cQwAF?p=preview

How to assign local variable to json response angular2 [duplicate]

This question already has answers here:
How do I return the response from an Observable/http/async call in angular?
(10 answers)
Closed 5 years ago.
I want to assign a json response which contains an array with the following:
0
:
{ID: 2, NAME: "asd", PWD_EXPIRY_IN_DAYS: 30}
1
:
{ID: 1, NAME: "Admin", PWD_EXPIRY_IN_DAYS: 30}
I have a local variable of type groups, which is like so
export class Group {
id: string;
name: string;
pwd_expiry_in_days: string;
}
Now I created an object of type Group in my component which I want to assign the json reply into, the following is not working and is showing undefined. Here is my code:
import { Injectable, Provider, ModuleWithProviders,Component, OnInit } from '#angular/core';
import { Http, Headers, Response, RequestOptions } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import {Group} from '../../_models/group'
import 'rxjs/add/operator/map';
interface Validator<T extends FormControl> {
(c: T): { [error: string]: any };
}
#Component({
selector: 'form1',
templateUrl: './form1.html',
moduleId: module.id,
})
export class Form1Component {
public roles: Group; // <--- variable to feed response into
private getGroups() : Observable<any> {
console.log("In Groups");
var responseAsObject : any;
let _url = groupsURL";
let headers = new Headers();
headers.append('X-User', sessionStorage.getItem('username'));
headers.append('X-Token', sessionStorage.getItem('token'));
headers.append('X-AccessTime', sessionStorage.getItem('AccessTime'));
headers.append('Content-Type', 'application/json');
let options = new RequestOptions({ headers: headers });
return this.http.get(_url, options)
.map(response => {
var responseAsObject = response.json();
console.log(responseAsObject); //<--- proper response
return responseAsObject;
})
}
constructor(private http: Http) {
this.getGroups()
.subscribe(data => {
this.roles = data;
console.log(this.roles); //<--- proper response
});
console.log(this.roles); //<----- undefined, I need the roles variable so I can use it on the front end
}
How can I fix this? I've been told its an Async issue, simply assigning this.roles = data (from the json response) is not working and shows up as undefined in my component (anywhere outside the scope of the subscription).
What is the proper method of assigning a response into my local variable in this case?
UPDATED with template to view the object, also being viewed as undefined:
<div class="form-group" [ngClass]="{'has-error':!complexForm.controls['group_id'].valid}">
<label>Group ID</label>
<div class="row">
<div class="col-md-4">
<select name="group_id" id="group_id" class="form-control" [formControl]="complexForm.controls['group_id']" data-width='200px'>
<option *ngFor="let role of roles" [value]="role.id">
{{role.name}}
</option>
</select>
</div>
</div>
</div>
thank you!
What is the proper method of assigning a response into my local variable in this case?
You're not doing it wrong. You just need to be better prepared for it for be undefined and/or empty at the initial stages of the component construction.
The easiest thing to do is simply do an *ngIf="someArray.length" on an html node before iteration. something like:
// html
...
<div class="row" *ngIf="roles.length"><!-- Prevents un-populated array iteration -->
<div class="col-md-4">
<select class="form-control">
<option *ngFor="let role of roles" [value]="role.id">
{{role.name}}
</option>
</select>
</div>
</div>
There are some improvements you can make to your typescript as well, such as not changing the pointer of the array- this may save you some trouble later on -so instead of this.roles = data, use this.roles.length = 0; this.roles.push(...data);. For more info read up on Angular Change Detection.
// ts
export class Form1Component implements OnInit{
public roles: Array<Group> = []; // <--- isn't this an Array?
...
private getGroups() : Observable<any> {
var responseAsObject : any;
...
return this.http.get(_url, options)
.map(response => {
var responseAsObject = response.json();
return responseAsObject;
});
}
constructor(private http: Http) {}
ngOnInit(){
this.getGroups()
.subscribe(data => {
let groups = data.map(item=>{
return new Group(item)
});//<--- If you want it to be of type `Group`
this.roles.length = 0;
this.roles.push(...groups);
});
}
...
}
You second console log will run before your api call because api calls are asynchronous. Please try to make the type of role any like publice role: any if its works then you have to modify your Group model.