how to pass interface based property in Angular - javascript

export interface Iresumedata {
shortIntro: string,
fullIntro: string,
mob: number,
email: string,
profile: any
}
import {
Component,
OnInit
} from '#angular/core';
import {
ResumedataService
} from "../../services/resumedata.service";
#Component({
selector: 'app-experience',
templateUrl: './experience.component.html',
styleUrls: ['./experience.component.scss']
})
export class ExperienceComponent implements OnInit {
experiencedata: any = [];
constructor(private resumeservice: ResumedataService) {}
ngOnInit() {
this.resumeservice.getresumedata().subscribe(data => (this.experiencedata = data.experience));
}
}
I am trying to fetch data through service and successfully getting it, but the thing is whenever I am passing property such as experience or profile based on JSON object, its continuously throwing error like.
Property 'experience' does not exist on type 'Iresumedata[]'
where Iresumedata is my interface, guys how can I remove this error? Kindly take a look, what exactly should I do?

Please follow these step.
Your interface structure should be like
export interface Iresumedata {
shortIntro: string,
fullIntro: string,
mob: number,
email: string,
profile ?: any,
experience ?:any,
}
Import Iresumedata into your dashboard component
Use it like
this.resumeservice.getresumedata().subscribe(data:Iresumedata=>{ (this.experiencedata = data.experience)});

Related

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

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);

TypeScript "Property does not exist on type" error when setting up a "Profile Details" page in Angular

I know this is an extremely simple question but I have yet to find a resource solution that will work or explain in a way that makes complete sense. I'm trying to get back into Angular after many years and never used TypeScript before. Currently struggling a lot with errors and what TypeScript is actually expecting me to do.
I have an app that connects to the Open Brewery DB. I'm trying to make a details page that fetches data based on an :id URL param.
app.com/breweries, give me a list of breweries
app.com/breweries/:id, give me specific details on that brewery
I have a list component that grabs a list of Breweries. So whatever comes back gets displayed in a list.
http.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { IBrewery } from './brewery/brewery';
#Injectable({
providedIn: 'root'
})
export class HttpService {
constructor(private http: HttpClient) { }
getBreweries() {
return this.http.get('https://api.openbrewerydb.org/breweries');
}
getBrewery(id) {
return this.http.get<IBrewery[]>(`https://api.openbrewerydb.org/breweries/${id}`)
}
}
list.component.ts
import { Component, OnInit } from '#angular/core';
import { HttpService } from '../http.service';
#Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.scss']
})
export class ListComponent implements OnInit {
breweries: Object;
constructor(private _http: HttpService) { }
ngOnInit(): void {
this._http.getBreweries().subscribe(data => {
this.breweries = data;
});
}
}
list.component.html
<h1>Breweries</h1>
<ul *ngIf="breweries">
<li *ngFor="let brewery of breweries">
<p class="name">{{ brewery.name }}</p>
<p class="country">{{ brewery.country}}</p>
Visit Website
</li>
</ul>
So all this works no errors everything seems fine...then comes the profile and where things break down.
brewery.component.ts
import { Component, OnInit } from '#angular/core';
import {ActivatedRoute} from '#angular/router';
import { HttpService } from '../http.service';
#Component({
selector: 'app-brewery',
templateUrl: './brewery.component.html',
styleUrls: ['./brewery.component.scss']
})
export class BreweryComponent implements OnInit {
brewery: object = {};
breweryId: string;
constructor(private _http: HttpService, private activatedRoute: ActivatedRoute) { }
ngOnInit(): void {
this.breweryId = this.activatedRoute.snapshot.params.id;
this._http.getBrewery(this.breweryId).subscribe(data => {
this.brewery = data;
})
}
}
brewery.component.html
<ul *ngIf="brewery">
<li>
{{brewery.name}}
</li>
<li>
{{brewery.city}}, {{brewery.state}}
</li>
</ul>
brewery.ts
export interface IBrewery {
name: string,
city: string,
state: string
};
The errors I'm getting are:
- ERROR in src/app/brewery/brewery.component.html:7:13 - error TS2339: Property 'name' does not exist on type 'object'.
- Error occurs in the template of component BreweryComponent.
src/app/brewery/brewery.component.html:10:13 - error TS2339: Property 'city' does not exist on type 'object'.
- Error occurs in the template of component BreweryComponent.
src/app/brewery/brewery.component.html:10:31 - error TS2339: Property 'state' does not exist on type 'object'.
So the problem I believe is that brewery needs to have assigned properties and types associated to those properties before I can declare them in the component template. If that is true, for the life of me I cannot figure out how or where I'm supposed to take the IBrewery and properly use it. I've seen examples where it gets used in the service as well as the mycomponent.component.ts file. In either instance it's about as clear as mud on how to fix the problem.
Short Answer: use Safe Navigation Operator
Update your html as below.
<ul *ngIf="brewery">
<li>
{{brewery?.name}}
</li>
<li>
{{brewery?.city}}, {{brewery?.state}}
</li>
</ul>
Better approach: use a loading spinner.
<div *ngIf="loading">
some loading spinner
</div>
<div *ngIf="!loading">
<li>
{{brewery?.name}}
</li>
<li>
{{brewery?.city}}, {{brewery?.state}}
</li>
</ul>
export class BreweryComponent implements OnInit {
brewery; // be default type will be any.
breweryId: string;
loading = false; // loading spinner.
constructor(private _http: HttpService,
private activatedRoute: ActivatedRoute) { }
ngOnInit(): void {
this.breweryId = this.activatedRoute.snapshot.params.id;
this.get();
}
get() {
this.loading = true;
this._http.getBrewery(this.breweryId)
.subscribe(data => {
this.brewery = data;
this.loading = false; // loading spinner hidden.
}, (error) => {
// handle error;
});
}
}
First of all, you should get the correct typing in your service. It should look like this:
getBreweries() {
return this.http.get<IBrewery[]>('https://api.openbrewerydb.org/breweries');
}
getBrewery(id) {
return this.http.get<IBrewery>(`https://api.openbrewerydb.org/breweries/${id}`)
}
As you can see, I added the expected type to getBreweries and changed the expected type in getBrewery(id). I'm not sure why it was set to IBrewery[] before, since you told us it should only give one specific detail of a brewery.
Now, when you subscribe to these, the parameter inside the subscibe function will be inferred to be the types you have set in the get type parameter. Therefore, it's a good idea to set the type of the component instance variable to that type too, like this:
export class ListComponent implements OnInit {
breweries: IBrewery[];
...
}
and
export class BreweryComponent implements OnInit {
brewery: IBrewery;
...
}
In general, you don't want to use the type object or Object, because it tells you nothing about the structure of the type. If you don't know the exact structure of your type or are too lazy to create an interface, you should use any.
And btw, the reason why the ListComponent worked to begin with was kinda lucky. the let x of y syntax is allowed for y of type object for some reason, and it seems like x is inferred to as any, so you could write whatever you wanted without getting an error. It's important to understand that typescript won't change anything in runtime, so the runtime types will be whatever they are no matter what your typescript types say.

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.

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;
}

'object' does not contain such a member Angular 5

I am new to Angular and trying to make a small application.
I referred 'object' does not contain such a member
answer but I am not getting my solution from there.
profile.component.ts
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '#angular/router';
#Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
user: Object;
constructor(private authService: AuthService, private roter: Router) {}
ngOnInit() {
this.authService.getProfile().subscribe(
profile => {
this.user = profile.user;
},
err => {
console.log(err);
return false;
}
);
}
}
profile.component.html
<div *ngIf="user">
<h2 class="page-header">
{{ user.name }}
</h2>
<ul class="list-group">
<li class="list-group-item">
Username: {{ user.username }}
</li>
<li class="list-group-item">
Email: {{ user.email }}
</li>
</ul>
</div>
Visual studio code is showing this
Error:
[Angular] Identifier 'username' is not defined. 'Object' does not contain such a member
property user of ProfileComponent
Either change
user: Object;
by
user: any;
In your profile.component.ts this will surely work,because initially you have declared it as object so while running the or building app typescript compilation fails due to accessed as user.username.
Either you change the type to any or create interface or type having required properties and assign this type to user
Ex:
profile.component.ts:
interface userObject {
username:string,
password:string
}
access as
export class ProfileComponent implements OnInit {
user : userObject;
}
you have defined user in ProfileComponent class as Object type.wich has no Typescript Model defined.Therefore Typescript is unaware of the structure of the User Object.
So you create a model like this.
interface User{
username : String;
password: ...
....
}
and then use it as type like user : User
The problem will be solved.
When you define an object it doesn't have firstName or lastName. So when accessing from ui it shows the error. So first initialize as given below. Then the issue will be solved.
let user = {firstName: "", lastName:""};
Code:
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '#angular/router';
#Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
let user = {firstName: "", lastName:""};
constructor(private authService: AuthService, private roter: Router) {}
ngOnInit() {
this.authService.getProfile().subscribe(
profile => {
this.user = profile.user;
},
err => {
console.log(err);
return false;
}
);
}
}
Object refers to the inbuilt object constructor function, which obviously doesn't have the property username. Since you're setting the type of user to be Object and trying to access the property username that doesn't exist, it's showing error.
If you want to define your own types, refer this.

Categories