I am using Nest Serialization to transform api response. However, it returns really crypic result. I expect it to slice some fields out of the data but for some reason, it shows weird result.
product.entity.js
export class ProductEntity {
id: string
description: string
status: boolean
price: string
moq: number
rating: number
last_modified: string
constructor(partial: Partial<ProductEntity>) {
Object.assign(this, partial)
}
}
product.controller.ts
#UseInterceptors(ClassSerializerInterceptor)
#Get()
async findAll(
#Query('page') page: number,
#Query('per_page') per_page: number
): Promise<ProductEntity[]> {
if (!page && !per_page) {
throw new BadRequestException('Proper query params not supplied')
}
const data: ProductEntity[] = []
const products: any = await this.productService.findAll({
page,
per_page
})
products.map(product => {
data.push(new ProductEntity(product))
})
return data
}
product.service.ts
async findAll(query): Promise<Product[]> {
const { page, per_page }: { page: number; per_page: number } = query
const from: number = (page - 1) * per_page
return this.productModel
.find()
.skip(from)
.limit(Number(per_page))
}
which returns,
"$__": {
"strictMode": true,
"selected": {},
"getters": {},
"_id": {
"_bsontype": "ObjectID",
"id": {
"type": "Buffer",
"data": [
93,
15,
149,
140,
78,
148,
77,
10,
10,
105,
51,
130
]
}
},
"wasPopulated": false,
"activePaths": {
"paths": {
"moq_type": "init",
"moq": "init",
"price_type": "init",
"price": "init",
"name": "init",
"category_id": "init",
"company_id": "init",
"short_description": "init",
"long_description": "init",
"active": "init",
"variations": "init",
"keywords": "init",
"photos": "init",
"_id": "init",
"created_at": "init",
"updated_at": "init",
"__v": "init"
},
"states": {
"ignore": {},
"default": {},
"init": {
"_id": true,
"short_description": true,
"long_description": true,
"active": true,
"variations": true,
"keywords": true,
"photos": true,
"name": true,
"price": true,
"price_type": true,
"moq": true,
"moq_type": true,
"category_id": true,
"company_id": true,
"created_at": true,
"updated_at": true,
"__v": true
},
"modify": {},
"require": {}
},
"stateNames": [
"require",
"modify",
"init",
"default",
"ignore"
]
},
"pathsToScopes": {},
"cachedRequired": {},
"session": null,
"$setCalled": [],
"emitter": {
"_events": {},
"_eventsCount": 0,
"_maxListeners": 0
},
"$options": {
"skipId": true,
"isNew": false,
"willInit": true
}
},
Am I doing something wrong in here or is it not correct way to transform API response?
Not sure about NestJS but in regular node.js for mongodb, If you are calling find() that way X().X().X() you need to add at the end of the pipeline the call to exec() method, like :
this.productModel
.find()
.skip(from)
.limit(Number(per_page))
.exec();
I am getting that too. The answer is removed #UseInterceptors(ClassSerializerInterceptor) in your controller.
Maybe that function utilize object inheritance from class extension? I think you don't really need it because that function is used to cast a response (like tranforming camerCase to snake_case, etc). If you really need it, then I don't know because I am still strugle with it too.
Related
I am trying to fetch information from: https://games.roblox.com/v1/games?universeIds=3759152694
But having it try to response with "response.data[0]" (I use jsonpathfinder) it gives me undefined. When I try to do "response.data[0].id" it says that id is not defined. I have not messed with apis in quite a while so I may be just missing something here. Any help is appreciated!
const axios = require("axios");
module.exports = {
name: "info",
execute: async (bot, message, args) => {
test = {
data: [
{
id: 3759152694,
rootPlaceId: 10269801695,
name: "unnamed sim",
description: "soon",
sourceName: "unnamed sim",
sourceDescription: "soon",
creator: { id: 3593901883, name: "Jack1286401", type: "User", isRNVAccount: false, hasVerifiedBadge: false },
price: null,
allowedGearGenres: ["All"],
allowedGearCategories: [],
isGenreEnforced: false,
copyingAllowed: false,
playing: 0,
visits: 0,
maxPlayers: 6,
created: "2022-07-18T14:21:46.03Z",
updated: "2022-07-22T08:17:08.8213451Z",
studioAccessToApisAllowed: false,
createVipServersAllowed: false,
universeAvatarType: "MorphToR15",
genre: "All",
isAllGenre: true,
isFavoritedByUser: false,
favoritedCount: 0,
},
],
};
await axios.get("https://games.roblox.com/v1/games?universeIds=3759152694").then(function (response) {
// handle success
console.log(JSON.stringify(response.data[0]));
});
},
};
JSON Table:
{
"data": [
{
"id": 3759152694,
"rootPlaceId": 10269801695,
"name": "unnamed sim",
"description": "soon",
"sourceName": "unnamed sim",
"sourceDescription": "soon",
"creator": { "id": 3593901883, "name": "Jack1286401", "type": "User", "isRNVAccount": false, "hasVerifiedBadge": false },
"price": null,
"allowedGearGenres": ["All"],
"allowedGearCategories": [],
"isGenreEnforced": false,
"copyingAllowed": false,
"playing": 0,
"visits": 0,
"maxPlayers": 6,
"created": "2022-07-18T14:21:46.03Z",
"updated": "2022-07-22T08:17:08.8213451Z",
"studioAccessToApisAllowed": false,
"createVipServersAllowed": false,
"universeAvatarType": "MorphToR15",
"genre": "All",
"isAllGenre": true,
"isFavoritedByUser": false,
"favoritedCount": 0
}
]
}
Trying to access the mythic object and print the length of mythic's that exist in the account but unsure how to access it as its nested in the array. Api output is below Javascript. Just not sure exactly what I can use to get its length as I used json.mythic.length and that did not work. And Thank you very much to anyone who is able to help me with this problem.
function MyFunction(e) {
e.preventDefault();
var username = document.getElementById("username").value
document.getElementById("search").innerHTML = username;
const data = {
username, limit: 3000, offset: 0, rarities: [], markers: [], onSale: "", search: "" }
fetch("https://prod-eternal-backend.onrender.com/api/v1/moment/list" ,{
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then(response => {
return response.json();
})
.then(json => {
console.log(json);
document.getElementById("moments").innerHTML ="Total Moments = " + json.moments.length;
var mythics = json.mythic.length * 50;
document.getElementById("gamer").innerHTML ="Gamer Score = " + mythics;
})
}
{
"moments": [
{
"id": 114375,
"playId": 536,
"setId": 16,
"serialNumber": 4,
"username": "pattonh84",
"userId": 1230,
"userAuthId": "AqXfuefDt5a5wfqAoIa45O1RKbd2",
"influencer": "YuggieTV",
"influencerId": "YuggieTV",
"influencerAvatar": "https://eternal-zelos.s3.us-west-2.amazonaws.com/influencers/YuggieTV_square.png",
"playbackId": "QXMRHp9R4uFcSsCQkN7mBCDbSmFZdImdjeUHypEutRw",
"rarity": "mythic",
"createdAt": "2021-10-25T00:11:54.734962Z",
"setName": "Flow State",
"circulationCount": 30,
"title": "How Strong Could It Be?",
"imageURL": "https://eternal-zelos.s3.us-west-2.amazonaws.com/images/FlowFest/Let+Me+See+How+Strong+It+Is.png",
"packName": "Flow State",
"clipDate": "2021-09-26T02:55:28Z",
"tags": [
"funny"
],
"description": "Yuggie doing experiments in the name of science. Today's experiment is about how strong a watermelon could be.",
"game": "IRL",
"twitter": "yuggietv",
"staked": false,
"autographStatus": "false",
"discordUtility": false,
"markers": null
},
{
"id": 108262,
"playId": 565,
"setId": 16,
"serialNumber": 1,
"username": "pattonh84",
"userId": 1230,
"userAuthId": "AqXfuefDt5a5wfqAoIa45O1RKbd2",
"influencer": "Amouranth",
"influencerId": "Amouranth",
"influencerAvatar": "https://eternal-zelos.s3.us-west-2.amazonaws.com/influencers/Amouranth.jpg",
"playbackId": "101L8XUOTCKkJW3USj6rtiJm5k4iTAwTIMqcxfPsr8QA",
"rarity": "mythic",
"createdAt": "2021-10-22T17:07:38.357172Z",
"setName": "Flow State",
"circulationCount": 30,
"title": "Mare Awareness",
"imageURL": "https://eternal-zelos.s3.us-west-2.amazonaws.com/images/FlowFest/amouranth+pretending+to+be+a+horse.png",
"packName": "Flow State",
"clipDate": "2021-09-26T04:21:46Z",
"tags": [
"funny"
],
"description": "Now a popular gif, this clip showcases a horse performance complete with galloping and internal monalogue.",
"game": "Just Chatting",
"twitter": "Amouranth",
"staked": false,
"autographStatus": "pending",
"autographRequestId": 2071,
"discordUtility": false,
"markers": null
},
{
"id": 114393,
"playId": 536,
"setId": 16,
"serialNumber": 22,
"username": "pattonh84",
"userId": 1230,
"userAuthId": "AqXfuefDt5a5wfqAoIa45O1RKbd2",
"influencer": "YuggieTV",
"influencerId": "YuggieTV",
"influencerAvatar": "https://eternal-zelos.s3.us-west-2.amazonaws.com/influencers/YuggieTV_square.png",
"playbackId": "QXMRHp9R4uFcSsCQkN7mBCDbSmFZdImdjeUHypEutRw",
"rarity": "mythic",
"createdAt": "2021-10-22T03:35:24.934307Z",
"setName": "Flow State",
"forSale": true,
"circulationCount": 30,
"price": 200,
"title": "How Strong Could It Be?",
"imageURL": "https://eternal-zelos.s3.us-west-2.amazonaws.com/images/FlowFest/Let+Me+See+How+Strong+It+Is.png",
"packName": "Flow State",
"clipDate": "2021-09-26T02:55:28Z",
"tags": [
"funny"
],
"description": "Yuggie doing experiments in the name of science. Today's experiment is about how strong a watermelon could be.",
"game": "IRL",
"twitter": "yuggietv",
"staked": false,
"autographStatus": "false",
"discordUtility": false,
"productId": 67358,
"markers": null
}
],
"totalMoments": 3
}
You are trying to access a mythic property on your JSON object, but your data does not have such a property. I would recommend that you study more on JSON structure and accessing properties in javascript.
Basically, json.mythics checks for a property called mythics in the root level of your json object, the same way json.moments does. If your data was organized like:
{
"moments": [...],
"mythics": [...]
}
then you would access it with json.mythics
But your json only has a moments array of objects, some of which have a rarity property set to "mythic".
Assuming you want to filter out these elements from the array, a simple filter should suffice:
const mythics = json.moments.filter(moment => moment.rarity === 'mythic');
mythics.length // gives the length of the 'mythics'
I've been trying to get a list of all files in a specific folder of my storage bucket and it works pretty well but there is no information about the meta of the object as described in this document: https://cloud.google.com/storage/docs/json_api/v1/objects#resource
The shape of the item object is not the same and instead gives a "ReferenceCompat" for each item in the array.
Instead - the only provided properties are bucket, fullPath and name.
Does anyone know why this is?
https://firebase.google.com/docs/storage/web/list-files
const storageRef = firebase.storage().ref(folder);
const listFiles = function listFilesAndSaveToSlice() {
storageRef
.listAll()
.then((res) => {
res.items.forEach((item) => {
let {name, id, owner, acl, ...etc} = item;
// {name: name, id: undefined, ...undefined}
});
})
.catch((error) => {
});
};
This is the object provided instead of what's expected:
ReferenceCompat: {
"_delegate": {
"_service": {
"app": {
"name": "[DEFAULT]",
"automaticDataCollectionEnabled": false,
"options": {
"apiKey": "xxxxxxx-xxxxxxxxx",
"authDomain": "xxxxxx",
"projectId": "xxxx",
"storageBucket": "xxxxxx",
"messagingSenderId": "xxxxxxxxx",
"appId": "xxxxxxxx"
}
},
"_authProvider": {
"name": "auth-internal",
"container": {
"name": "[DEFAULT]",
"providers": {}
},
"component": {
"name": "auth-internal",
"multipleInstances": false,
"instantiationMode": "LAZY",
"type": "PRIVATE"
},
"instances": {},
"instancesDeferred": {},
"onInitCallbacks": {}
},
"_appCheckProvider": {
"name": "app-check-internal",
"container": {
"name": "[DEFAULT]",
"providers": {}
},
"component": null,
"instances": {},
"instancesDeferred": {},
"onInitCallbacks": {}
},
"_pool": {},
"_firebaseVersion": "8.6.5",
"_bucket": {
"bucket": "xxxxx",
"path_": ""
},
"_host": "firebasestorage.googleapis.com",
"_appId": null,
"_deleted": false,
"_maxOperationRetryTime": 120000,
"_maxUploadRetryTime": 600000,
"_requests": {}
},
"_location": {
"bucket": "xxxxxxxxxx",
"path_": "samples/coming to an end v2.mp3.asd"
}
},
"storage": {
"app": {
"name": "[DEFAULT]",
"automaticDataCollectionEnabled": false,
"options": {
"apiKey": "xxxxxx",
"authDomain": "xxxxxx",
"projectId": "xxxxx",
"storageBucket": "xxxxx",
"messagingSenderId": "xxxxx",
"appId": "xxxx"
}
},
"_delegate": {
"app": {
"name": "[DEFAULT]",
"automaticDataCollectionEnabled": false,
"options": {
"apiKey": "xxxxxxxxxxxxxx",
"authDomain": "xxxxxxx",
"projectId": "xxxxxx",
"storageBucket": "xxxxx",
"messagingSenderId": "xxxxx",
"appId": "xxxxxx"
}
},
"_authProvider": {
"name": "auth-internal",
"container": {
"name": "[DEFAULT]",
"providers": {}
},
"component": {
"name": "auth-internal",
"multipleInstances": false,
"instantiationMode": "LAZY",
"type": "PRIVATE"
},
"instances": {},
"instancesDeferred": {},
"onInitCallbacks": {}
},
"_appCheckProvider": {
"name": "app-check-internal",
"container": {
"name": "[DEFAULT]",
"providers": {}
},
"component": null,
"instances": {},
"instancesDeferred": {},
"onInitCallbacks": {}
},
"_pool": {},
"_firebaseVersion": "8.6.5",
"_bucket": {
"bucket": "megatech-ltd.appspot.com",
"path_": ""
},
"_host": "firebasestorage.googleapis.com",
"_appId": null,
"_deleted": false,
"_maxOperationRetryTime": 120000,
"_maxUploadRetryTime": 600000,
"_requests": {}
},
"INTERNAL": {}
}
}
As mentioned in the firebase storage api docs, list() returns a ListResult which in turn may contain multiple Reference objects.
If you want to fetch the metadata for all of the objects returned by list(), you'll need to call Reference.getMetadata() on each individual file returned.
’m trying to parse the response data to view property data. However, I searched through all the properties in the response data but none seemed to hold property data.
For anybody who isn’t familiar with realtor API this is the site I’m talking about. The data shows the exact way I want to receive mine
https://rapidapi.com/apidojo/api/realtor/endpoints
fetch("https://realtor.p.rapidapi.com/properties/v2/list-for-rent?sort=relevance&city=New%20York%20City&state_code=NY&limit=200&offset=0", {
"method": "GET",
"headers": {
"x-rapidapi-host": "realtor.p.rapidapi.com",
"x-rapidapi-key": "e5b0286ea4msh1d616284115d5efp16cadcjsn0392ca0398ac"
}
})
.then(response => {
console.log(response.json());
})
.catch(err => {
console.log(err);
});
I was able to use Postman and test this endpoint and found that you likely need to be looking for the properties array and loop through the objects and sub-arrays/objects contained in each parent object of the properties array to get to the details about each property.
Inside of this array are objects that contain the address, latitude, longitude, etc.
I would recommend using Postman if you are not already, doing a GET request when doing so and using the same headers. You should see the same. Using Postman is a great way to test endpoints!
Here is an example of the data that is returned from the results inside of the properties array when hitting your endpoint with a GET request:
"properties": [
...
...
{
"property_id": "R3188507190",
"listing_id": "612930061",
"prop_type": "apartment",
"list_date": "2018-08-20T17:22:00.000Z",
"last_update": "2020-08-25T08:17:00.000Z",
"year_built": 2018,
"listing_status": "active",
"beds": 0,
"prop_status": "for_rent",
"address": {
"city": "Arverne",
"country": "USA",
"county": "Queens",
"lat": 40.589922,
"line": "190 Beach 69th St",
"postal_code": "11692",
"state_code": "NY",
"state": "New York",
"time_zone": "America/New_York",
"neighborhood_name": "Rockaway Peninsula",
"neighborhoods": [
{
"id": "8c06e34c-3044-5621-aea4-b59d9ddde719",
"level": "macro_neighborhood",
"name": "Rockaway Peninsula"
}
],
"lon": -73.79765
},
"client_display_flags": {
"presentation_status": "for_rent",
"is_showcase": true,
"lead_form_phone_required": true,
"price_change": 0,
"has_specials": false,
"is_mls_rental": false,
"is_rental_community": true,
"is_rental_unit": false,
"is_co_star": true,
"is_apartmentlist": false,
"suppress_map_pin": false,
"suppress_phone_call_lead_event": true,
"price_reduced": false,
"allows_cats": true,
"allows_dogs": true,
"allows_dogs_small": true,
"allows_dogs_large": true
},
"agents": [
{
"primary": true
}
],
"lead_forms": {
"form": {
"name": {
"required": true,
"minimum_character_count": 1
},
"email": {
"required": true,
"minimum_character_count": 5
},
"move_in_date": {
"required": true,
"default_date": "2020-09-01T12:00:00Z",
"minimum_days_from_today": 1,
"maximum_days_from_today": 180
},
"phone": {
"required": true,
"minimum_character_count": 10,
"maximum_character_count": 11
},
"message": {
"required": false,
"minimum_character_count": 0
},
"show": false
},
"show_agent": false,
"show_broker": false,
"show_provider": false,
"show_management": false
},
"lot_size": {
"size": 0,
"units": "sqft"
},
"building_size": {
"units": "sqft"
},
"rdc_web_url": "https://www.realtor.com/realestateandhomes-detail/190-Beach-69th-St_Arverne_NY_11692_M31885-07190",
"rdc_app_url": "move-rdc://www.realtor.com/realestateandhomes-detail/190-Beach-69th-St_Arverne_NY_11692_M31885-07190",
"community": {
"baths_max": 1,
"baths_min": 1,
"beds_max": 1,
"beds_min": 1,
"contact_number": "(844) 454-2289",
"id": 1839240,
"name": "The Tides At Arverne By The Sea",
"price_max": 2195,
"price_min": 2195,
"source_id": "46dfexj",
"sqft_max": 659,
"sqft_min": 659
},
"data_source_name": "co-star",
"source": "community",
"page_no": 1,
"rank": 1,
"list_tracking": "type|property|data|prop_id|3188507190|list_id|612930061|comm_id|1839240|page|rank|data_source|co-star|property_status|product_code|advantage_code^1|1|3K2|E8|0^^$0|1|2|$3|4|5|6|7|8|9|G|A|H|B|C|D|I|E|J|F|K]]",
"photo_count": 19,
"photos": [
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f75218736o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f3178227471o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f3306091863o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f1799178643o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f884518299o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f1142482343o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f624998745o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f3641852832o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f2581754924o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f1976580515o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f586291969o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f2803556443o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f3294921843o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f852583007o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f4164216811o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f3902720508o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f850731407o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f2027588413o.jpg"
},
{
"href": "https://ar.rdcpix.com/610e208fe79b9533c5e103166312b312c-f805760224o.jpg"
}
]
},
...
...
]
If the response is not returning the data you expect then it could be that the format of your fetch GET request code is not quite right.
EDIT: In fact, that is exactly the problem I do believe. So, it should probably work if you try to structure your fetch similarly to this:
let url = 'https://realtor.p.rapidapi.com/properties/v2/list-for-rent?sort=relevance&city=New%20York%20City&state_code=NY&limit=200&offset=0';
fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'x-rapidapi-host': 'realtor.p.rapidapi.com',
'x-rapidapi-key': 'e5b0286ea4msh1d616284115d5efp16cadcjsn0392ca0398ac'
}})
.then((response) => {
return response.json();
})
.then((data) => {
console.log(data);
});
I have a result set returned from a mongodb query and am using lodash to reformat it. I am trying to convert the array of objects into a single object. The problem is when I use lodash on the result set, I get unexpected output.
NOTE: Running the snippet on codepen/codesandbox gives correct output, but not when used directly from mongoose results.
Mongoose Query
try {
const petInfo = await pets.find({ userId: user_id, petId: pet_id })
.select({
"_id": 0,
"createdAt": 0,
"updatedAt": 0,
"__v": 0
});
if(!petInfo) {
return res.status(400).json({ message: "FAILED_TO_FETCH_PET_INFO" });
}
let newObj = _.reduce(petInfo, (acc, cur)=> { return _.assign(acc, cur) }, {});
return res.status(200).json(newObj);
}
catch (error) {
req.errorMsg = error.message; // Log actual error
return res.status(500).json({ message: "SOME_ERROR_OCCURRED" });
}
Result from mongoose find query (petInfo)
[
{
"age": {
"days": "",
"months": "",
"years": ""
},
"userId": "45422605180207851194",
"name": "Oscar",
"gender": "FEMALE",
"type": "Dog",
"breed": "",
"weight": "",
"spayOrNeuter": false,
"petId": "KSVv7yJLnUWX3n"
}
]
Lodash snippet
let newObj = _.reduce(petInfo, (acc, cur)=> { return _.assign(acc, cur) }, {});
return res.status(200).json(newObj);
Result after modification
{
"$__": {
"strictMode": true,
"selected": {
"_id": 0,
"createdAt": 0,
"updatedAt": 0,
"__v": 0
},
"getters": {
"age": {
"days": "",
"months": "",
"years": ""
}
},
"wasPopulated": false,
"scope": {
"age": {
"days": "",
"months": "",
"years": ""
},
"userId": "45422605180207851194",
"name": "Oscar",
"gender": "FEMALE",
"type": "Dog",
"breed": "",
"weight": "",
"spayOrNeuter": false,
"petId": "KSVv7yJLnUWX3n"
},
"activePaths": {
"paths": {
"userId": "init",
"petId": "init",
"name": "init",
"gender": "init",
"type": "init",
"breed": "init",
"age.days": "init",
"age.months": "init",
"age.years": "init",
"weight": "init",
"spayOrNeuter": "init"
},
"states": {
"ignore": {},
"default": {},
"init": {
"userId": true,
"name": true,
"gender": true,
"type": true,
"breed": true,
"age.days": true,
"age.months": true,
"age.years": true,
"weight": true,
"spayOrNeuter": true,
"petId": true
},
"modify": {},
"require": {}
},
"stateNames": [
"require",
"modify",
"init",
"default",
"ignore"
]
},
"pathsToScopes": {},
"cachedRequired": {},
"session": null,
"$setCalled": {},
"emitter": {
"_events": {},
"_eventsCount": 0,
"_maxListeners": 0
},
"$options": {
"skipId": true,
"isNew": false,
"willInit": true
},
"nestedPath": "age"
},
"isNew": false,
"_doc": {
"age": {
"days": "",
"months": "",
"years": ""
},
"userId": "45422605180207851194",
"name": "Oscar",
"gender": "FEMALE",
"type": "Dog",
"breed": "",
"weight": "",
"spayOrNeuter": false,
"petId": "KSVv7yJLnUWX3n"
},
"$locals": {},
"$init": true
}
The reason for this is because mongoose doesn't return the object you think it does. Instead, it returns a 'mongoose' object with a bunch of methods ect ect. There are 2 ways around this, either call .lean() on your query or toJSON() on the result to sanitize result into normal js object.
.lean()
const petInfo = await pets.find({ userId: user_id, petId: pet_id })
.select({
"_id": 0,
"createdAt": 0,
"updatedAt": 0,
"__v": 0
}).lean();
.toJSON()
const petInfo = await pets.find({ userId: user_id, petId: pet_id })
.select({
"_id": 0,
"createdAt": 0,
"updatedAt": 0,
"__v": 0
}).lean();
const parsed = petInfo.toJSON()
Your query will return the result set as document objects instead of plain objects, which is why you get all the additional information like strictMode, getters, etc.
You could use the lean() function in order to get plain objects only (see https://mongoosejs.com/docs/tutorials/lean.html), e.g.:
const petInfo = await pets.find({ userId: user_id, petId: pet_id })
.select({
"_id": 0,
"createdAt": 0,
"updatedAt": 0,
"__v": 0
}).lean();