Jade Template Trouble accessing Values from view data - node.js

I've passed an object to my jade template from express:
connection.invokeQuery(sqlStatement, function(rows){
res.render('index', { title: 'App', companies: rows});
});
here's my template
extends layout
block content
h1= title
div
each company in companies
p #{company.City}
that works, I can render a city list. But I'm not sure how to get at the root property or sub properties and objects within an object with jade.
For example lets say the json for company was this:
[{
companyName: 'Apple',
City: 'Milwaukee',
State: 'WI ',
StateName: 'Wisconsin',
Country: 'United States',
Region: 'North America',
PostalCode: '53201-0371'},
{
Website: 'www.apple.com',
....
},
... and so on
}]
I tried company.companyName and it doesn't work.
Also how would I reference the property "Website"? It's in another object below in this array.

From what I'm seeing here, you have multiple objects inside an array. You wouldn't be able to access "Website" as it is in another object. The each statement is iterating over the array containing your objects. You could access it in the second iteration of your each statement, but no other properties of the first object. If you wanted access to that value, it must be a part of the same object.

Related

How to search through multiple documents having object as field value for a keyword using index "text" in MongoDB?

I want to search if a keyword present in any of the fields in documents. some field values are objects.so it is also needed to check whether the keyword present inside that object also.
so I came across the following solution.
collections: products(having companyId as foreign key), company
mongoQuery
db.products.aggregate([{$match:{$text:{$search:"hello"}}},{$lookup:{from:"companies",localField:"companyId",foreignField:"_id",as:"company"}},{$unwind:"$company"}])
result
`
[
{
_id: ObjectId("63832de4e9dbcd9b2942ded7"),
companyId: [ ObjectId("6383048ae9dbcd9b2942dece") ],
title: 'hello world',
imageUrl: 'https://drive.google.com/file/image',
company: {
_id: ObjectId("6383048ae9dbcd9b2942dece"),
name: 'name1',
url: 'name1.com'
}
}
]
`
But problem is that i have another document where 'company.name' having value "hello".By using above query it doesn't return the second document.How can i solve this problem?
$or is your correct approach: https://www.mongodb.com/docs/manual/reference/operator/query/or/
Just use it with .find as example links shows and you will get an array of documents.

Massive.js selecting specific nested fields from document

I have the following document sturcture stored in a document table
{
firstname: '',
surname: '',
...
manager: {
firstname: '',
surname: ''
...
}
}
When selecting records with Massive.js i can limit the fields returned by providing an options object.
await dbConn.table.findDoc(criteriaObj, { fields: ['firstname', 'surname'] });
This works great for root fields, but for nested objects; consider the manager field above, Massive returns that field as a JSON string rather than a parsed object.
await dbConn.table.findDoc(criteriaObj, { fields: ['firstname', 'manager'] });
Which returns the following.
[{
firstname: 'bob',
manager: '{"firstname":"","surname":""}'
}]
I've trawled through Massive's documentation and not been able to find any reference to using this feature with nested fields.
Is this even possible? Ideally I'd like to craft an options object where i can request any number of fields from the root document but also select any subset of fields from nested objects within that document.
Any information would be greatly appreciated thanks.

How to find an object inside an array inside a mongoose model?

I'm trying to query an object that's inside an item which is inside a mongoose model, when I'm trying to find that object with the find() method or _.find() method, I can't get access to the object for some reason and when I console.log() it, it gives me undefined or when I use array.filter() it gives me an empty array, which means the object that I'm trying to access does not meet the criteria that I give it in the lodash find method, but then when I look at my database I see that the object does actually have the properties to meet the criteria. So I don't know what I'm doing wrong, here's my code: as you can see I'm trying to get the information of the item that the user clicked on and want to see:
router.get("/:category/:itemId", (req, res) => {
console.log(req.params.itemId);
//gives the item id that the user clicked on
console.log(req.params.category);
//gives the name of category so I can find items inside it
Category.findOne({ name: req.params.category }, (err, category) => {
const items = category.items; //the array of items
console.log(items); //gives an array back
const item = _.find(items, { _id: req.params.itemId });
console.log(item); //gives the value of 'undefined' for whatever reason
});
});
The category Schema:
const catSchema = new mongoose.Schema({
name: {
type: String,
default: "Unlisted",
},
items: [
{
name: String,
price: Number,
description: String,
img: String,
dateAdded: Date,
lastUpdated: Date,
},
],
dateCreated: Date,
lastUpdate: Date,
});
well the answer is a little bit obvious, you are using MongoDB and in Mongo you have "_ID" you can use that "_ID" only with Mongoose! so you just have to remove the underscore and that is it! do it like this const item = _.find(items, { id: req.params.itemId });
hope you are doing better.
When I look at your Schema I see that the item field is an array of objects which doesn't have an _id inside so when you create a new instance of catShema it just generates an _id field for the new instance but not for each item inside the items array, just also enter the id of the item in question because according to my understanding, you must also have a model called items in your database
When you save these records in your database, you will generate an element with this structure
{
_id: String, // auto generated
name: String,
items: [ {"name1", "price1", "description1", "imgUrl1", "dateAdded1", "lastUpdated1"},{"name2", "price2", "description2", "imgUrl2", "dateAdded1", "lastUpdated2"}, ...],
dateCreated: Date,
lastUpdate: Date
}
Note : the code provided at the top is only an illustration of the object which will be registered in the database and not a valid code
Here you can notice that there is not a field called _id in the object sent inside the database.
My suggestion to solve this issue is
To create an additional field inside the items array called _id like :
{
...,
items: [
{
_id: {
type: String,
unique : true,
required: true // to make sure you will always have it when you create a new instance
},
...
... // the rest of fields of items
},
...
Now when you create a new instance make sure in the object you enter in the database the _id is recorded when you call the catInstance.save() so inside the catInstance object you have to add the current Id of the element to be able to filter using this field.
Hope my answer helped, if you have any additional questions, please let me know
Happy coding ...

How to best reach into MongoDb Mongoose Schema objects which use lists of other objects

I am learning my way around MongoDB data types and the best way to use documents and Schemas through Mongoose.
I've defined a couple of Schemas for a Navigation bar object which stores the navigation items as a list, and each item is defined by a schema with the properties name, type, url, and a list of drop downs if it has any (if the type is "dropdown").
Here are those Schemas:
var navSchema = new Schema({
id: String,
items: [Schema.ObjectId]
});
is the nav object, and
var navItemSchema = new Schema({
name: String,
type: {type: String, default: "link"},
url: {type: String, default: null},
dropdowns: {type: [Schema.ObjectId], default: null}
});
is the nav item schema, but each nav item can potentially have dropdowns, and so the dropdowns is a list of nav items, which can also potentially have dropdowns. But in this case, only a few do.
Now to create the data for these objects, I have to do something like this to create a nav item, example for "home"
var home = new navItem({
name: "home",
url: "/home"
});
but for items with dropdowns, I have to define all the items I know will be dropdowns before defining list which includes those items, and then defining the parent item and using the list with those items I just defined. Like this
var allAccessories = new navItem({
name: "all accessories",
url: "/accessories"
});
var cushions = new navItem({
name: "cushions",
url: "/accessories#cushions"
});
var cupHolders = new navItem({
name: "cup holders",
url: "/accessories#cupholders"
});
var accessoriesDropdownItems = [
allAccessories,
cushions,
cupHolders
];
var accessories = new navItem({
name: "accessories",
type: "dropdown",
dropdowns: accessoriesDropdownItems
});
So, I assume I'm doing that right..? My only gripe with this method is that in my nav.js file where I create this mongodb object/collection, I have to think about what items are going to be used in dropdowns of other items, and so I have to theoretically order them to be defined before the other variables are defined in the document.
But if I then want to use an item in two dropdown lists, and one of those dropdownlists I happened to have already defined above it in the document but now want to add to. I have to move the item definition above anywhere it's used, this ruins the organisation of the document..
But I'm okay with physically indenting to keep my work organised and sorted.
My question is how do I actually access properties of objects within lists of other objects.
Straight up I define Nav as simply an object with an id, "nav" because I don't want to use its _id ObjectId to reference it all the time...? And an items array which contains the navItemsSchema objects.
But when I try to reach into these objects through mongo shell using something like
db.navs.find({items: {$elemMatch: {name:"home"}}})
Or
db.navs.find({items: ObjectId("58d5d6df0789f718460ff278")})
Or
db.navs.find({items:{ "name" : "home"}})
I can't get any data back.. I have successfully manage to return all objects in the collection through the node app via responding found nav in navs
app.get('/nav', function(req, res) {
mongoose.model('nav').find(function(err, nav) {
res.send(nav);
});
});
But all this returns me is a data structure with object id's and not the actually data of the objects.
{"_id":"58d5d6df0789f718460ff287",
"id":"nav","__v":0,
"items":
["58d5d6df0789f718460ff278",
"58d5d6df0789f718460ff279",
"58d5d6df0789f718460ff286",
"58d5d6df0789f718460ff281",
"58d5d6df0789f718460ff282",
"58d5d6df0789f718460ff283",
"58d5d6df0789f718460ff284"
]
}
Could you please help me understand how I reach into these data hierarchies via say db.navs.nav("nav").items.findAll() and it lists all the items and their json?
Or is this not possible and you need to loop through all items, then. Wait, where are the objects stored corresponding to ObjectId's in the items list?
So I actually figured it out myself. I was using type: [Schema.ObjectId] (ie. type was a list of Schema.ObjectIds) but I didn't know that that automatically parses the inputted list of objects and extracts just their ObjectId's and stores them, all I need to do was make the type: [] (ie. just a list) and then I can traverse my nav object simply by... Oh wait, for some reason when mongoose nav.saves my nav it becomes an object inside a list. So when I mongoose.model('nav').find(function(err, nav) {} it gives me a nav object which I need to use via nav[0].items[0].name Or I can go nav = nav[0] but I wish I didn't need to do this step? Maybe there's an answer but yes. Otherwise. This is the solution I was looking for.

Why doesn't this data display?

I have the following JSON object:
{
user:
{
city: 'San Francisco',
country: 'US',
displayName: 'Bernard',
weightUnit: 'METRIC'
}
}
It comes back in the following piece of code, i.e. as a string:
var response = results[0];
I send it to the view like this:
res.render('user', {title: 'User Details', result: JSON.parse(response)});
In the view, no matter what I do, I cannot access displayName.
All I want is to this in my jade template:
h1 Hi, #{displayName}
And I keep getting user undefined, undefined of undefined, etc.
No matter how I try and access that displayName, jade/express simply cannot get to it.
Anyone have any ideas how I'd do this please?
That object that you pass in your render call becomes the context your Jade file uses. Thus, at your root, you have title and result. See where this is going?
Try h1 Hi, #{result.user.displayName}.

Resources