I am getting '[object Object]' from service to component using Angular - javascript

Please help on the below issue this is my model class. I tried all the possible ways using .pipe.map() import {map} from rxjs/operators method, but still giving [object Object]
export class AppProfilesDetailsDO {
envName?: string;
envDesc?: string;
envIpAddress?: string;
envProfileName?: string;
envCrDeployed?: string;
envUrl?: string;
envAdminConsoleUrl?: string;
envDbSchema?: string;
envDbUserId?: string;
envGisSchema?: string;
envPortNo?: number;
}
my component class
import { Component, OnInit } from '#angular/core';
import { ProfileserviceService } from './profileservice.service';
import { AppProfilesDetailsDO } from '../models/AppProfilesDetailsDO';
#Component({
selector: 'app-profiledetails',
templateUrl: './profiledetails.component.html',
styleUrls: ['./profiledetails.component.css']
})
export class ProfiledetailsComponent implements OnInit {
appProfileData: AppProfilesDetailsDO[];
constructor(private profileService: ProfileserviceService) { this.appProfileData = [] }
ngOnInit() {
console.log("In profiledetails component");
this.profileService.getProfileSetUpDetails().subscribe(
appProfileData => {
this.appProfileData = appProfileData;
}
);
console.log("Compenent Profile Data: "+this.appProfileData); ==> **in my console it is
printing as ==> [object Object] **
}
}
My service component
import { HttpClient } from "#angular/common/http";
import { Injectable } from "#angular/core";
import { Observable } from "rxjs";
import { AppProfilesDetailsDO } from "../models/AppProfilesDetailsDO";
#Injectable({
providedIn: 'root'
})
export class ProfileserviceService {
BASE_PATH:string = "http://localhost:8080/getProfileSetUpDetails";
constructor(private httpClient: HttpClient) {}
httpOptions = {
headers: new Headers ({
'Content-type': 'application/json'
})
}
appProfileData?: AppProfilesDetailsDO[];
getProfileSetUpDetails() : Observable<AppProfilesDetailsDO[]> {
return this.httpClient.get<AppProfilesDetailsDO[]>(this.BASE_PATH);
}
}
I am not sure where it is wrong. Please help on this issue.
Thanks.

The problem is this line console.log("Compenent Profile Data: "+this.appProfileData);. You are trying to concatenate an object with a string.
Simply change that line to console.log("Compenent Profile Data: ", this.appProfileData);
For more clarity look at this example:
var data = { a: "ali" };
console.log("Compenent Profile Data: " , data); console.log("Compenent Profile Data: " + data);

If you want to see the result it should be like this
console.log("Component Profile Data:", this.appProfileData);
other ways it will try to log the concatenated value of string with the result object which is impossible

You can not impose concatenation in between string and an array of object as you did like this:
console.log("Compenent Profile Data: "+this.appProfileData);
So, just use like this instead and problem will be gone:
console.log(this.appProfileData);

Related

How to pass json data to Class variable in Angular?

I have a class Projects
export class Projects {
project_id: number;
project_name: string;
category_id: number;
project_type: string;
start_date: Date;
completion_date: Date;
working_status: string;
project_info: string;
area: string;
address: string;
city: string;}
Its Service class is
#Injectable()
export class ProjectsService {
constructor(private http: HttpClient) {}
//http://localhost:9090/projectInfo
private apiUrl = 'http://localhost:9090/projectInfo';
public findAll() {
return this.http.get(this.apiUrl);
}
getProducts(): Observable<ProjectsModule[]> {
return this.http.get<ProjectsModule[]>(this.apiUrl);
}
Component is
import { Component, OnInit } from '#angular/core';
import { ProjectsService } from '../projects.service';
import{Projects} from '../projects';
import { plainToClass, Transform, Expose, Type, Exclude } from 'class-transformer';
#Component({
selector: 'app-project-list',
templateUrl: './project-list.component.html',
styleUrls: ['./project-list.component.css'],
providers: [ProjectsService]
})
export class ProjectListComponent implements OnInit {
private projects:Projects[]=[];
stringObject: any;
constructor(
private projectsService: ProjectsService) { }
vandana='rahul';
ngOnInit() {
this.getAllProjects();
}
getAllProjects() {
this.projectsService.getProducts().subscribe((data: Projects[])=> {
this.stringObject =JSON.stringify(data)
let newTodo = Object.assign(new Projects(), data);
this.projects= <Projects[]>this.stringObject;
console.log("data -"+ this.projects)
console.log("Array -"+ this.stringObject)
console.log("data -"+ this.projects[1].project_info)
},
err => {
console.log(err);
}
);
}
When i am trying to read newTodo.project_id (or any property of class Projects) it is undefined
but newtodo is returning jsondata
output is
Please help me in getting values newtodo.project_id, newtodo.project_name and so on
You're assigning a JSON string to this.projects.
The JSON string is [{"projectId": 1, ... }].
So:
this.projects[1] evaluates to { (i.e. the second character in the string)
"{".project_id evaluates to undefined
You should assign the data itself to this.projects:
this.projects = data;
And then keep in mind that arrays in JavaScript are zero-based. Since you only have one object in your array, you'd have to print the projectId as follows:
console.log(this.projects[0].projectId);
Also, the properties of your Projects class don't match your JSON at all. Furthermore, Projects should probably be named Project, and should be an interface instead of a class.

Extracting data from model to variables

I'm new to typescript and angular and I was trying to fetch some data from firebase using angularfire2 and assign it to variables to use in some other functions later. I'm only familiar with javascript dot notation where I access members of the object using dot notation seems like it doesn't work with angular can somebody please help me with extracting data from the model to variables, please
I'm still having a hard time understanding Observable and subscribes too.
code
model
export class Reacts {
sad?: number;
happy?: number;
neutral?: number;
}
service
import { Injectable } from "#angular/core";
import {
AngularFirestore,
AngularFirestoreCollection,
AngularFirestoreDocument
} from "angularfire2/firestore";
import { Reacts } from "../models/reacts";
import { Observable } from "rxjs";
#Injectable({
providedIn: "root"
})
export class ReactService {
mapCollection: AngularFirestoreCollection<Reacts>;
reacts: Observable<Reacts[]>;
constructor(public afs: AngularFirestoreDocument) {
this.reacts = this.afs.collection("reacts").valueChanges();
}
getItems() {
return this.reacts;
}
}
component
import { Component, OnInit } from "#angular/core";
import { Reacts } from 'src/app/models/reacts';
import { ReactService } from 'src/app/services/react.service';
#Component({
selector: "app-reacts",
templateUrl: "./reacts.component.html",
styleUrls: ["./reacts.component.css"]
})
export class ReactsComponent implements OnInit {
react: Reacts[];
happy: number;
sad: number;
neutral:number;
constructor(private reactsService: ReactService ) {}
ngOnInit(): void {
this.reactsService.getItems().subscribe(reacts => {
this.react = reacts;
console.log(reacts); //this works print an array object of data from database
this.happy= reacts.happy// what i'm trying to achieve
});
}
}
Ok, I'll break it down for you. You are trying to access .happy but it is actually an array of React[]
ngOnInit(): void {
this.reactsService.getItems().subscribe((reacts:Reacts[]) => { // Note I have defined its model type
this.react = reacts;
console.log(reacts); //this works print an array object of data from database
//this.happy= reacts.happy // Now VS code will show you error itself
this.happy = reacts[0].happy;
});
}
The power of typscript comes as it is strongly typed language. If you'll make changes as below in service, the VS Code will itself explain you the error:
export class ReactService {
mapCollection: AngularFirestoreCollection<Reacts>;
reacts: Observable<Reacts[]>;
constructor(public afs: AngularFirestoreDocument) {
this.reacts = this.afs.collection("reacts").valueChanges();
}
getItems(): Observable<Reacts[]> { // added return type
return this.reacts;
}
}
Once I provide return type of getItems() , you dont even have to define type in .subscribe((reacts:Reacts[]) as I have done in your component.

_co.photo is undefined console error and error context, but code works as expected

I got problem with angular component.
When I make my component with selector, it works as expected: execute httpget, and render photo with title.
But in console I got two errors:
ERROR TypeError: "_co.photo is undefined"
View_PhotoHolderComponent_0 PhotoHolderComponent.html:2
and
ERROR CONTEXT
...
PhotoHolderComponent.html:2:8
View_PhotoHolderComponent_0 PhotoHolderComponent.html:2
I got html:
<div class="photo-holder">
<h2>{{photo.title}}</h2>
<img src="{{photo.url}}">
</div>
and ts:
import { Component, OnInit } from '#angular/core';
import { Photo } from './photo'
import { PhotoDeliveryService } from '../photo-delivery-service.service'
#Component({
selector: 'app-photo-holder',
templateUrl: './photo-holder.component.html',
styleUrls: ['./photo-holder.component.css']
})
export class PhotoHolderComponent implements OnInit {
photo:Photo
constructor( private photoService : PhotoDeliveryService) {
}
ngOnInit() {
this.photoService.getRandomPhoto().subscribe((data: Photo) => this.photo = {...data})
}
}
and service :
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Photo } from './photo-holder/photo'
#Injectable({
providedIn: 'root'
})
export class PhotoDeliveryService {
value : Number
url : string
constructor(private http: HttpClient) {
this.url = "https://jsonplaceholder.typicode.com/photos/";
this.value = Math.floor(Math.random() * 10) + 1;
}
getRandomPhoto() {
return this.http.get<Photo>(this.getUrl())
}
getUrl(){
return this.url + this.value;
}
}
I suspect that could be made by binding property before query results was returned.
How can I rid off this problem, can I wait for this query, or this is different kind of problem ?
You are getting the error because before your service could resolve, the template bindings are resolved and at that time photo object is undefined.
first thing, you can initialize the photo object but then you might have to detect the changes using ChangeDetectorRef to reflect the value returned by the service.
photo:Photo = {
title:'',
url:''
};
constructor( private photoService : PhotoserviceService, private cdr:ChangeDetectorRef) {
}
ngOnInit() {
this.photoService.getRandomPhoto().subscribe((data: Photo) => {
this.photo = data;
this.cdr.detectChanges();
});
}

Adding a Sub Class to All Angular Models

I am using AngularJS for web app and in that I am trying to read data from APIs. Thus i have made few Models in accordance with the API's result set. Among many Models, Lets talk about a single Model TYPE
//This is the JSON API is returning
{
"records":[
{
"ID":"1",
"TYPE":"mythological"
}
],
"pagination":{
"count":"1",
"page":1,
"limit":10,
"totalpages":1
}
}
Now I have made the following Model for TYPE
//type.ts
export class Type {
"ID":string;
"TYPE":string;
}
After fetching the data from API i am successfully storing it and running through my code using following TYPE component ts.
//gallery.component.ts
import { Component, OnInit } from '#angular/core';
import { DataService } from 'src/app/services/data.service';
import { Type } from 'src/app/models/type';
#Component({
selector: 'app-gallery',
templateUrl: './gallery.component.html',
styleUrls: ['./gallery.component.scss']
})
export class GalleryComponent implements OnInit {
types: Type;
constructor(private data: DataService) { }
ngOnInit() {
}
clickfunction(){
this.data.getData().subscribe(data=>{
this.types=data.records;
console.log(this.types);
});
}
}
ALso, i am fetching data from this service
//data.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class DataService {
dataUrl:string = 'http://localhost/api-slim/public/index.php/api/info/type';
constructor(private http: HttpClient) { }
getData() {
return this.http.get(this.dataUrl);
}
}
Although the application is running its obviously giving me the following error, which i need to radicate.
Date: 2019-09-26T19:42:06.903Z - Hash: a1b41d5889df87ba0aa3
5 unchanged chunks
Time: 780ms
ℹ 「wdm」: Compiled successfully.
ERROR in src/app/components/gallery/gallery.component.ts(23,21): error TS2339: Property 'records' does not exist on type 'Object'.
NOW
The pagination data that the API is providing is common in each of the API response, but as you can see none of my models are consuming it. What would be the best way to store and use that pagination in each of my model. I have tried to made a temporary demo class in gallery.component.ts as follows,
export class TEMP {
records: TYPE[];
pagination: [];
}
But it's ugly. Is there any efficient fix?
Your model class doesn't really reflect the API response.
A model is like a custom data structure that you can use like a data type like this:
export TEMP { //consider renaming this to something more meaningful
records: Array<Type>;
pagination: Pagination;
}
export class Type {
ID: string;
TYPE: string;
}
export Pagination{
count: string;
page: number;
limit: number;
totalpages: number;
}

Angular 5 - HTTP Client - converting resp.body to Array

I am trying to get my JSON response from the HttpClient service into an array so that I can loop through using *ngFor in my html. I've tried using "this" to loop through but *ngFor will not accept it. Below is the code for my service.ts component and the main component.ts.
I just need some way to convert an array from "resp.body" into an exportable Array to be used for string interpolation in the html. Any help would be much appreciated!
races.component.ts
import { Component, OnInit } from '#angular/core';
import {Race, RacesService} from './races.service';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'dh-races',
templateUrl: './races.component.html',
providers: [ RacesService ],
styleUrls: ['./races.component.scss']
})
export class RacesComponent {
error: any;
headers: string[];
race: Race;
raceM: any[];
constructor(private racesService: RacesService) {
var raceM = [];
var raceArray = [];
this.racesService.getRaceResponse()
.subscribe(resp => {
raceArray.push(resp.body);
for (let obj of raceArray) {
for (let i in obj) {
raceM.push({
"ID": obj[i].id + ",",
"Date": obj[i].activityStartDate,
"RaceName": obj[i].assetName,
"Website": obj[i].website
})
}
console.log(raceM);
return raceM;
}
});
}
races.service.ts
#Injectable()
export class RacesService {
constructor(private httpClient: HttpClient) { }
getRace() {
return this.httpClient.get(activeApiURL).pipe(
retry(3),
catchError(this.handleError)
);
}
getRaceResponse(): Observable<HttpResponse<Race>> {
return this.httpClient.get<Race>(
activeApiURL, {
observe: 'response'
});
}
To fix the issue, you need to create an interface that matches the data you get from the server, I will call this interface IRace.
Then in the component I will create a variable named races, I will assign the returned value from the server response i.e. resp.body to the races variable.
I'd change the service to look like this:
export interface IRace {
// Your response from server object's properties here like so:
id: Number;
assetName: string;
...
}
export class RacesService {
constructor(private httpClient: HttpClient) { }
getRace() {
return this.httpClient.get(activeApiURL).pipe(
retry(3),
catchError(this.handleError)
);
}
getRaceResponse(): Observable<HttpResponse<Array<Race>>> {
return this.httpClient.get<Array<Race>>(
activeApiURL, {
observe: 'response'
});
}
}
Finally, I'd change the race component to this:
import { Component, OnInit } from '#angular/core';
import { Race, RacesService, IRace } from './races.service';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'dh-races',
templateUrl: './races.component.html',
providers: [ RacesService ],
styleUrls: ['./races.component.scss']
})
export class RacesComponent {
error: any;
headers: string[];
races: IRace[];
constructor(private racesService: RacesService) {
this.racesService.getRaceResponse()
.subscribe(resp => {
this.races = resp.body;
});
}
}
I hope this helps.

Categories