I'm a bit of a beginner in angular 4... tried to search for this many times in the past few months, but got no result, even though it seems the most simple thing.
It's an ionic app. User logs in, the whole user object is saved to localStorage. Have tried several plugins, but went with simple:
window.localStorage.setItem('User', JSON.stringify(user));
user object structure:
export class User {
constructor(
public token?: string,
public user_email?: string,
public email?: string,
public first_name?: string,
public last_name?: string,
public user_roles?: {
ID?: number,
caps?: {
administrator?: boolean,
},
roles?: object,
},
public id?: number,
public device_feedback?: boolean,
public role?: string,
public username?: string,
public billing?: Address,
public shipping?: Address
) {}
}
export class Address {
first_name?: string;
last_name?: string;
company?: string;
address_1?: string;
address_2?: string;
city?: string;
state?: string;
postcode?: string;
country?: string;
email?: string;
phone?: number
}
settings.ts: (I have added ngOnInit and this.platform.ready(){} because thought data is not ready or something...)
export class Settings implements OnInit{
[other vars]
user: User;
constructor(public storage: Storage, private platform: Platform) { }
ngOnInit() {
// this.storage.ready().then(() => {
// this.storage.get("User").then((data) => {
this.platform.ready().then(() => {
let data = window.localStorage.getItem('User');
if (data) {
this.user = JSON.parse(data);
this.email = this.user.user_email;
console.log('user', this.user);
console.log('this.user.user_email', this.user.user_email);
}
});
}
Settings.html
<ion-content>
<ion-list padding>
<ion-list-header>
Title
</ion-list-header>
<ion-item>
<ion-label color="primary" fixed>Email</ion-label>
<ion-input class="in" type="email" [(ngModel)]="user.user_email" disabled="true"></ion-input>
</ion-item>
The user_email is displayed in the console.log, referenced as this.user.user_email and same property gives an error in the HTML... how is this possible? Same in the browser or the device: http://prntscr.com/i8rfhg
I have also tried with user: any, but got the same result...
How? Why? What am I missing?
Here's the ionic info:
#ionic/cli-utils : 1.19.1
ionic (Ionic CLI) : 3.19.1
global packages:
cordova (Cordova CLI) : 7.1.0
local packages:
#ionic/app-scripts : 1.3.0
Cordova Platforms : none
Ionic Framework : ionic-angular 3.0.1
System:
Android SDK Tools : 25.2.5
Node : v6.11.0
npm : 5.6.0
Thanks a lot!
You are trying to access the property user_email of your user object while it's null / before it's initialized.
Try:
user: User = {}; // initial value
Or:
<ion-list padding *ngIf="user">
<ion-list-header>
Title
</ion-list-header>
<ion-item>
<ion-label color="primary" fixed>Email</ion-label>
<ion-input class="in" type="email" [(ngModel)]="user.user_email" disabled="true"></ion-input>
</ion-item>
you don't have instance of User in this.user.
export class User {
public token: string;
public user_email: string;
public email: string;
public first_name: string;
public last_name: string;
public user_roles : Object = {
ID: null,
caps: {
administrator: false,
},
roles: {},
};
public id: number;
public device_feedback: boolean;
public role: string;
public username: string;
public billing: Address;
public shipping: Address;
public set(data:any){
if(!data){
return;
}
this.token = data.token;
this.user_email = data.user_email;
this.email = data.email;
this.first_name = data.first_name;
this.last_name = data.last_name;
this.id = data.id;
this.device_feedback = data.device_feedback;
this.role = data.role;
this.username = data.username;
this.billing = data.billing;
this.shipping = data.shipping;
this.user_roles = data.user_roles;
} }
and
export class Settings implements OnInit{ [other vars]
user: User = new User(); constructor(public storage: Storage, private platform: Platform) { }
ngOnInit() {
// this.storage.ready().then(() => {
// this.storage.get("User").then((data) => {
this.platform.ready().then(() => {
this.user.set(window.localStorage.getItem('User'));
});
}
In ngOnInit, the callback for this.platform.ready() is executed asynchronously. Before that, user is undefined and [(ngModel)]="user.user_email" causes an error.
You can prevent that error with the safe navigation operator. Since it works only for one-way data binding, you should split [(ngModel)] in its two parts, [ngModel] and (ngModelChange). In addition to that change, you can keep the input element disabled until user is initialized, to prevent entering data that will be lost anyway.
[ngModel]="user?.user_email" (ngModelChange)="setUserEmail($event)" [disabled]="!user"
with the component method:
setUserEmail(value: string): void {
if (this.user) {
this.user.user_email = value;
}
}
The code is illustrated in this stackblitz, where the user object is initialized after a few seconds.
I use export interface and class.
export interface UserCaps
administrator: boolean;
}
export interface UserRole {
ID: null;
caps: UserCaps;
roles: any;
}
export interface Address {
first_name?: string;
last_name?: string;
company?: string;
address_1?: string;
address_2?: string;
city?: string;
state?: string;
postcode?: string;
country?: string;
email?: string;
phone?: number
}
export interface User {public token: string;
user_email: string;
email: string;
first_name: string;
last_name: string;
user_roles : UserRole;
id: number;
device_feedback: boolean;
role: string;
username: string;
billing: Address;
shipping: Address;
}
export class User {}
And i init my user with new Class()
user = new User();
Related
I'm trying to make API orders. The problem appears when I want to display all orders from the database using the GET method, but I get a 500 error and a message
CastError: Cast to ObjectId failed for value "order" (type string) at path "_id" for model "Product"
order.schemas.ts
#Schema()
export class Order {
#Prop()
username: string;
#Prop()
phone: string;
#Prop()
email: string;
#Prop()
adr: string;
#Prop({type: [{type: mongoose.Schema.Types.ObjectId, ref: 'Product'}]})
products_id: Product[];
}
product.schema.ts
#Schema()
export class Product {
#Prop()
name: string;
#Prop()
catalog_number: string;
#Prop()
old_price: number;
#Prop()
price: number;
#Prop()
desc_text: string;
#Prop()
desc_short: string;
#Prop()
image: string;
#Prop({type: [{type: mongoose.Schema.Types.ObjectId, ref: 'Order'}]})
orders: Order[];
}
This is file order.controller
#Controller('/order')
export class OrderController {
constructor(private orderServise: OrderService) { }
#Post()
create_order(#Body() dto: CreateOrderDto) {
return this.orderServise.create_order(dto);
}
#Get()
get_All() {
return this.orderServise.get_All();
}
#Get(':id')
getOne(#Param('id') id: ObjectId) {
return this.orderServise.getOne(id);
}
#Delete(':id')
delete(#Param('id') id: ObjectId) {
return this.orderServise.delete(id);
}
}
This is file order.service
#Injectable()
export class OrderService {
constructor(#InjectModel(Product.name) private productModule: Model<ProductDocument>,
#InjectModel(Order.name) private orderModule: Model<OrderDocument>) {}
async create_order (dto: CreateOrderDto): Promise<Order> {
const order = await this.orderModule.create({...dto });
return order;
}
async get_All(): Promise<Order[]> {
const order = await this.orderModule.find()
return order;
}
async getOne(id: ObjectId): Promise<Order>{
const order = await this.orderModule.findById(id).populate('products_id');
return order;
}
async delete(id: ObjectId): Promise<Order>{
const order = await this.orderModule.findOneAndDelete(id);
return order._id;
}
}
Что может быть не так? Потратил кучу времени на это!
I have created a base model class with is a model for the incoming data, I will be modeling the data inside of a class for some external reasons. Although I ran into a problem with is defining the incoming data into this model class.
This is my class
export class EntityBasic {
constructor(
public id: string,
public title: string,
public urn?: string,
public risk_level?: string,
public be_aware?: string,
public body?: string,
public published_at?: string,
public created_at?: string,
public updated_at?: string,
public description?: string,
public notes?: string,
) {}}
}
How I define the content inside of it in another page:
public getEntity(setEntity) {
return new EntityBasic(
setEntity.id,
setEntity.title,
setEntity?.urn,
setEntity?.risk_level,
setEntity?.be_aware,
setEntity?.body,
setEntity?.published_at,
setEntity?.created_at,
setEntity?.updated_at,
setEntity?.report?.summary || '',
setEntity?.report?.metadata?.source_notes,
setEntity?.report?.metadata?.notes,
);
}
But defining the data like so, gave me problems, since some times there won't be a urn, or a risk_level for example, and the data will be messed up inside the class.
I would like a way to define like so (This didnt work):
public getEntity(setEntity) {
return new EntityBasic(
id = setEntity.id,
title = setEntity.title,
urn = setEntity?.urn,
risk_level = setEntity?.risk_level,
)
}
I believe wrap all parameters into one object is the best solution.
Wrap them as interface
interface EntityBasicParameters {
id: string;
title: string;
urn?: string;
risk_level?: string;
be_aware?: string;
body?: string;
published_at?: string;
created_at?: string;
updated_at?: string;
description?: string;
notes?: string;
}
Accept only this object as constructor parameter
export class EntityBasic {
constructor(params: EntityBasicParameters) {}}
}
Now you can pass existent data only
public getEntity(setEntity) {
return new EntityBasic({
id: setEntity.id,
title: setEntity.title,
urn: setEntity?.urn,
risk_level: setEntity?.risk_level,
})
}
or just
public getEntity(setEntity) {
return new EntityBasic(setEntity)
}
How I can use getter and setter in TypeORM.
I saw issues in here and also here, but not found answer
For example a left my User entity
export class User {
#PrimaryGeneratedColumn()
private id: number;
#Column()
#Length(4, 20)
#IsNotEmpty()
private name: string;
#Column()
#Length(4, 100)
#IsNotEmpty()
private password: string;
public getId(): number {
return this.id;
}
public getPassword(password: string): string {
return this.password;
}
public setPassword(password: string): User {
this.password = bcrypt.hashSync(password, 8);
return this;
}
public setName(name: string): User {
this.name = name;
return this;
}
}
I use TypeORM version 0.2.7
#BeforeInsert & #AfterLoad
BeforeInsert https://typeorm.io/#/listeners-and-subscribers/beforeinsert
AfterLoad https://typeorm.io/#/listeners-and-subscribers/afterload
Use #BeforeInsert as setter
#Entity()
export class Post {
#BeforeInsert()
updateDates() {
this.createdDate = new Date()
}
}
Use #AfterLoad as getter
#Entity()
export class Post {
#AfterInsert()
resetCounters() {
this.counters = 0
}
}
How to create new instance in TypeScript. Obviously I'm not matching the constructor but I can't see what's wrong.
export class User implements IUser {
public id: number;
public username: string;
public firstname: string;
public lastname: string;
public birthday: string;
public email: string;
public constructor(iUser: IUser)
{
this.id = iUser.id;
this.username = iUser.username;
this.firstname = iUser.firstname;
this.lastname = iUser.lastname;
this.birthday = iUser.birthday;
this.email = iUser.email;
}
}
interface IUser {
id?: number;
username: string;
firstname: string;
lastname: string;
birthday: string;
email: string;
}
And student class that extends user
export class Student extends User implements IStudent, IUser {
public indeks: string;
public studyProgram: StudyProgram;
public constructor(iUser: IUser, iStudent: IStudent)
{
super(iUser);
this.indeks = iStudent.indeks;
this.studyProgram = iStudent.studyProgram;
}
}
interface IStudent {
indeks: string;
studyProgram: StudyProgram;
}
So, when I try to create new instance of student I got this error
Supplied parameters do not match any signature of call target.
this.student = new Student ({
username: '',
firstname: '',
lastname: '',
birthday: '',
email: '',
indeks: '',
studyProgram: new StudyProgram({
name: '',
duration: 0,
courseType: ''
})
});
And here is StudyProgram class
export class StudyProgram implements StudyProgramInterface {
public id: number;
public name: string;
public duration: number;
public courseType: string;
public studentList: Array<Student>;
public constructor(studyProgramCfg: StudyProgramInterface) {
this.id = studyProgramCfg.id;
this.name = studyProgramCfg.name;
this.duration = studyProgramCfg.duration;
this.courseType = studyProgramCfg.courseType;
}
}
interface StudyProgramInterface {
id?: number;
name: string;
duration: number;
courseType: string;
}
The Student class constructor is expecting two objects (one implementing IStudent, and the other implementing IUser), you are passing only one. I think the constructor you are looking for is:
public constructor(student: IUser & IStudent) {
super(student);
this.indeks = student.indeks;
this.studyProgram = student.studyProgram;
}
You can find more about intersection types here: https://basarat.gitbooks.io/typescript/content/docs/types/type-system.html
i need a bit of help.
I am trying to display data from specific loged in user but i have a hard time.
in html :
<div *ngFor="let to of UnData">
TS:
export class something {
todo: AngularFireList<any>;
UnData = [];
userId: string;
constructor(public navCtrl: NavController, public navParams: NavParams, private db: AngularFireDatabase, private fire: AngularFireAuth) {
this.fire.authState.subscribe(user =>{
if(user) this.userId = user.uid
});
if (!this.userId) return;
this.db.list("people/${this.userId}").valueChanges().subscribe(_data => {
this.UnData = _data;
console.log(this.UnData);
});
}
console.log gives me nothing in return. I think i am doing something wrong in code where i am getting data from database. Please give me a bit of help :-)
Thanks Frank,
the first problem was backticks but i still had problems and solved and important part was ngOnInit(userId:string):
export class something {
todo: AngularFireList<any>;
unData = [];
userId: string;
title: string;
desc: string;
constructor(public navCtrl: NavController, public navParams: NavParams, private db: AngularFireDatabase, private fire: AngularFireAuth) {
this.fire.authState.subscribe(user => {
if (user) {
this.userId = user.uid;
console.log(this.userId);
}
});
}
postDatatoDB(title: string, desc: string, userId: string): void {
this.db.list("/tasks/" + this.userId).push({ title: title, desc: desc });
this.title = '';
this.desc = '';
}
**ngOnInit(userId:string)** {
this.db.list<any>(`/tasks/${this.userId}`).valueChanges().subscribe(data => {
this.unData = data;
console.log(this.unData);
});
}
}