I am using nest js in my sample application. I define the entity of my application .Entity means a document. But I struck at one place to define the location.
using mongoose I define the schema of my document like this see link
https://raw.githubusercontent.com/webmakaka/Node.js-API-Masterclass-With-Express-MongoDB/master/api/models/Bootcamp.js
location: {
// GeoJSON Point
type: {
type: String,
enum: ['Point']
},
coordinates: {
type: [Number],
index: '2dsphere'
},
formattedAddress: String,
street: String,
city: String,
state: String,
zipcode: String,
country: String
},
careers: {
// Array of strings
type: [String],
required: true,
enum: [
'Web Development',
'Mobile Development',
'UI/UX',
'Data Science',
'Business',
'Other'
]
},
same thing I want to do using typeorm using mongoDB without mongoos .can you please help me how I will do that.
here is my entity class
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, ManyToOne, ObjectID, ObjectIdColumn } from 'typeorm';
import { IsNotEmpty, MaxLength } from 'class-validator';
#Entity('bootcamp')
export class BootcampEntity extends BaseEntity {
#ObjectIdColumn() id: ObjectID;
#Column({type:'text',unique:true,length:50,nullable: false})
name:string;
#Column({type:'text'})
slug: string;
#Column({type:'text',length:500,nullable: false})
description: string;
#Column({type:'text'})
website: string;
#Column({type:'text',length:20})
phone: string;
#Column({type:'text',})
email: string;
#Column({type:'text',nullable: false})
address: string;
#Column({type:'text',array: true })
careers: string[];
#Column({type:'int'})
averageRating:number
#Column({type:'int'})
averageCost:number
//
#Column({type:'string',default:'no-photo.jpg'})
photo: string;
//
#Column({type:'boolean',default:false})
housing: boolean;
#Column({type:'boolean',default:false})
jobAssistance: boolean;
#Column({type:'boolean',default:false})
jobGuarantee: boolean;
#Column({type:'boolean',default:false})
acceptGi: boolean;
#Column({type:'date',default:Date.now()})
createdAt: Date;
}
I am using this framework
https://docs.nestjs.com/
typeorm link
https://typeorm.io/#/entities
there is schema
https://raw.githubusercontent.com/webmakaka/Node.js-API-Masterclass-With-Express-MongoDB/master/api/models/Bootcamp.js
I want make same schema using typeorm .I struck only defining the location attribute ?
how to define ?could you please tell me how I will define location in my entity class ?
I think location would have similar structure to code below.
source 1
source 2
enum GeoJSONPoint {
Point = "Point"
}
enum Careers {
WebDevelopment = 'Web Development',
MobileDevelopment = 'Mobile Development',
UIUX = 'UI/UX',
DataScience = 'Data Science',
Business = 'Business',
Other = 'Other'
}
#Entity('location')
export class LocationEntity extends BaseEntity {
#Column({
type: "enum",
enum: GeoJSONPoint
})
type: GeoJSONPoint;
#Column({type:'int'})
coordinates: number;
#Column({type:'text'})
formattedAddress: string;
#Column({type:'text'})
street: string;
#Column({type:'text'})
city: string;
#Column({type:'text'})
state: string;
#Column({type:'text'})
zipcode: string;
#Column({type:'text'})
country: string;
#Column({type:'simple-array'})
careers: Careers[];
}
Related
I am having difficulty in mapping one object to another object in Type script especially when objects contain different types and properties
interface PassengerV1 {
firstName: string;
lastName: string;
address: Address;
temp1:strng;
temp2:string;
phoneNumbers: PhoneNumber[];
}
interface PassengerV2 {
firstName: string;
lastName: string;
address: Address;
}
interface ObjectA{
lossCause: string;
lossDate: string;
vehicleInformation: {
vehicle: [
{
passengerInformation: {
passenger: PassengerV1[];};
}
];
};
}
interface ObjectB{
lCause: string;
lDate: string;
vehicleInfo: {
vehicle: [
{
passengerInformation: {
passenger: PassengerV2[];
};
];
};
}
const requestData: ObjectB= {
lCause: ObjectA.lossCause,
lDate: ObjectA.lossDate,
vehicleInformation: vehicleInfo??
}
Above is the ObjectB, iam building from Object A but got stuck with vehicle information. Researched map, objectfromentries but not clear how can be applied with child types differ in properties?
I've a dto called updateUserDTO and the class looks like this
#IsString()
full_name: string;
#IsNumber()
mobile: string;
#IsEmail()
email: string;
#IsOptional()
location: string;
#IsOptional()
landmark: string;
#IsOptional()
city: string;
How can I create a nested DTO, so when my response I post to my controller looks like this
{
"full_name": "xyz",
"mobile": 1231341451,
"email": "xyz#abc.com",
"address": {
"location": "new avenue",
"landmark": "Opp to St louis",
"city": "Buffalo"
}
}
you can use automapper to do that check the doc here :
https://automapperts.netlify.app/docs/nestjs
Just class-transformer for nested validation.
Divide you JSON into Parts
Do the use of class-transformer to validate a nested object
For Example
import { Type } from 'class-transformer';
import { IsDefined, IsNotEmptyObject, IsOptional, IsString,
ValidateNested } from 'class-validator';
// ################# Second Level Class #################
export class SecondLevel {
#IsOptional()
location: string;
#IsOptional()
landmark: string;
#IsOptional()
city: string;
}
// ############## First Level Class ###############
export class firstLevel {
#IsString()
full_name: string;
#IsNumber()
mobile: string;
#IsEmail()
email: string;
#IsDefined()
#IsNotEmptyObject()
#ValidateNested()
#Type(() => SecondLevel)
address: SecondLevel;
}
This question already has answers here:
How can I clone a JavaScript object except for one key?
(25 answers)
Closed 1 year ago.
I have two objects with two different types, I want to use one object to assign another.
interface From {
type: string;
timestamp: number;
aid?: string;
bid?: string;
cid?: string;
did?: string;
eid?: string;
fid?: string;
gid?: string;
}
interface To {
fromSocketID: string;
type: string;
timestamp: number;
aid?: string;
bid?: string;
cid?: string;
did?: string;
eid?: string;
fid?: string;
}
const from: From = {
type: "aaa",
timestamp: 1231231231,
gid: "ddd"
};
// Method1
const to1: To = {
fromSocketID: "temp",
type: from.type,
timestamp: from.timestamp
};
if (from.aid) {
to1.aid = from.aid
}
if (from.bid) {
to1.bid = from.bid;
}
if (from.cid) {
to1.cid = from.cid;
}
// ...three more if statements
// Method2
const to2: To = {
fromSocketID: "temp",
...from
}
// #ts-ignore
delete to2.gid;
interface To has a fromSocketID which From doesn't, and To lacks a gid property. In my real work scenario, I use Method1. I tried Method2, but i had to use ts-ignore. I wonder if there is a better solution.
You can use the rest operator to deconstruct the 'from', ignoring the gid property, like so:
interface From {
type: string;
timestamp: number;
aid?: string;
bid?: string;
cid?: string;
did?: string;
eid?: string;
fid?: string;
gid?: string;
}
interface To {
fromSocketID: string;
type: string;
timestamp: number;
aid?: string;
bid?: string;
cid?: string;
did?: string;
eid?: string;
fid?: string;
}
const from: From = {
type: "aaa",
timestamp: 1231231231,
gid: "ddd"
};
const { gid, ...rest } = from;
const to: To = {
fromSocketID: "temp",
...rest
};
Typescript is complaining at this line:
user.posts.pull(postId);
I am getting this error:
Property 'pull' does not exist on type 'PostDoc[]'
since postId is received as req.params.postId it is type string, so i converted it to mongoose objectId but i still have the same error:
user.posts.pull(mongoose.Types.ObjectId(postId));
pull() works in mongoose arrays. this line of code how I implemented in javacsript. I am converting my project to typescript. this is the user interface and schema for user model.
interface UserDoc extends mongoose.Document {
email: string;
password: string;
posts: PostDoc[];
name: string;
status: string;
}
const userSchema = new Schema({
email: { type: String, required: true },
password: { type: String, required: true },
name: { type: String, required: true },
status: { type: String, default: "I am a new user" },
posts: [{ type: Schema.Types.ObjectId, ref: "Post" }],
});
Here post schema and interface
interface PostDoc extends Document {
title: string;
content: string;
imageUrl: string;
creator: Types.ObjectId;
}
const postSchema = new Schema(
{
title: {
type: String,
required: true,
},
imageUrl: {
type: String,
required: true,
},
content: {
type: String,
required: true,
},
creator: {
type: Schema.Types.ObjectId,
ref: "User",
required: true,
},
},
{ timestamps: true }
I faced a similar problem to properly type the subdocuments. I propose you the following solution in order to keep both the DTO interface and the model interface separated and strongly typed. The same would apply for your PostDoc.
UserDoc DTO
interface UserDoc {
email: string;
password: string;
posts: PostDoc[];
name: string;
status: string;
}
UserDoc Model
export type UserDocModel = UserDoc & mongoose.Document & PostDocModel & Omit<UserDoc , 'posts'>
interface PostDocModel {
posts: mongoose.Types.Array<PostModel>;
};
We replace the posts: PostDoc[] property with Omit for our mongoose array of PostModel, maintaining the properties synchronized. Inspiration from https://stackoverflow.com/a/36661990
In this way we could access every mongoose array method such as pull, pop, shift, etc. (https://mongoosejs.com/docs/api.html#Array)
const user = await this.userdocModel.findById(userId).exec();
user.posts.pull(postId);
Exporting the model
const User = mongoose.model<UserDocModel>('User', userSchema);
export default User;
I am trying to push new objects to an array in my Angular 2 app, but I am running into an issue (which I suspect may be a Typescript type issue, though I'm not certain). This is what the array I'm pushing to looks like:
locations = [
{ city: 'Los Angelas', postalCode: '90001', coordinates: 2321 },
{ city: 'New York', postalCode: '10001', coordinates: 3432 },
];
And here is the function I am using to push new zipcodes to the array with:
addZipcode(event) {
this.locations.push({ postalCode: this.newPostalCode });
this.newPostalCode = '';
this.addZipInput = false;
event.preventDefault();
}
The error I'm getting re: this function is:
Argument of type '{ postalCode: any; }' is not assignable to parameter
of type '{ city: string; postalCode: string; coordinates: number; }'.
Property 'city' is missing in type '{ postalCode: any; }'.
How can I deal with this issue? Users will be pushing postalCodes, not cities or coordinates. I would think I could push an object of any kind to the array, but it seems typescript is preventing this.
TypeScript has inferred array type as { city: string; postalCode: string; coordinates: number; }[] , but you are trying to push {postalCode:string} - this is error. If you still want to do this then it is necessary to set appropriate type for location:
location:any[]
//or
interface ILocation {
city?:string;
postalCode?:string;
coordinates?:string;
}
location:ILocation[];
You can declare locations as array of objects with optional city and coordinates:
type Loc = {city?: string; postalCode: string; coordinates?: number};
let locations: Loc[] = [
{ city: 'Los Angelas', postalCode: '90001', coordinates: 2321 },
{ city: 'New York', postalCode: '10001', coordinates: 3432 },
];