Pug able to access a nested array from a mongo database Json - arrays

I am trying to output the array dependencies from the mongodb object. I have tried nearly everything but keep getting length of undefined.
I can output the whole object but I want the name version of each dependencies.
{ _id: 5c6eea28c6c23a15beb43419,
Repo_id: [ 1 ],
name: 'express-ibm',
version: '0.0.0',
dependencies:
[ { name: 'async', version: '2.6.1' },
{ name: 'body-parser#1.18.3', version: '1.18.3' },
{ name: 'cookie-parser#~1.4.3', version: '1.4.3' },
{ name: 'debug#~2.6.9', version: '2.6.9' },
{ name: 'express#~4.16.0', version: '4.16.4' },
{ name: 'http-errors#~1.6.2', version: '1.6.3' },
{ name: 'mongoose', version: '5.3.13' },
{ name: 'morgan#~1.9.0', version: '1.9.1' },
{ name: 'pug#2.0.0-beta11', version: '2.0.0-beta11' } ] }
// Display detail page for a specific Repo
exports.repo_search = function(req, res, next) {
Repo.findById(req.params.id).populate('repo').exec(function(err, repo) {
if (err) {
return next(err);
}
if (repo == null) {
// No results.
var err = new Error('Repo copy not found');
err.status = 404;
return next(err);
}
console.log(repo);
Repo.find().exec(function(err, list) {
if (err) {
return next(err);
}
res.render('repo_info_detail', {
title : 'Repo Detail',
repo : repo,
list : list
// repo_dependencies: results.repo_search
});
});
});
};
Pug:
extends layout
block content
p#demo
h1 #[Repository Name :] #{repo.name}
dd #[ IBM Github URL:]
a(href='/'+repo.url) #{repo.url}
dd #[ Repository ID:] #{repo._id}
dd #[ Language Type:] #{repo.filetype}
dd #[Repo ID :] #{repo.Repo_id}
//dd #[dependencies: ] #{repo.dependencies.name}
div(class='col')
div(class='col-sm-8')
p
button.hidediv Hide dependencies
button.showdiv Show dependencies
.divdemo
| Dependencies
.button
a#export(href='#', role='button')
| Click On This Here Link To Export The Table Data into a CSV File
div(class='col')
div(class='col-sm-3')
table
thead
tr: th Name
tbody
each d in repo
tr
td
dd #{repo}

repo is a javascript object, and you're correctly accessing its properties using dot syntax (e.g. repo.name or repo.dependencies). However, repo.dependencies is an array of objects. It doesn't have a name property that can accessed using dot syntax. Instead, you'll have to loop through the child objects and access each of their name properties in turn.
h1 Repository Name: #{repo.name}
dl
dt IBM Github URL:
dd #[a(href='/'+repo.url) #{repo.url}]
dt Repository ID
dd #{repo.Repo_id}
dt Dependencies
each dependency in repo.dependencies
dd #{dependency.name} (v#{dependency.version})
Have a look at the syntax for pug tab interpolation, it looks like you're using it incorrectly in your example.
Also, check out the documentation on the proper usage of dd elements and how they should be used with dt elements. They also must be children of a description list (dl) element: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl

Related

Gatsby-plugin-sitemap, custom config, need to integrate pages and markdown using custom resolvePages and Serialize, what does this line of code do?

just starting with javascript and react thanks to Gatsby so excuse me if this is a total newbie question. Also just starting with posting on stackoverflow, usually just consuming content, sorry about that and if my post is incomplete or unclear in anyway.
I am building a website using GatsbyJs, and want to setup a proper sitemap using gatsby-plugin-sitemap, however i am strugling to understand what the following line of code does so i can try and customize de code to do what I need, which is integrate the pages and blog posts on the sitemap, and adding a proper lastmod when applicable. I am breaking my head but cannot get the last part to work, that is, adding lastmod when it is a blog post.
on gatsby-config.js:
{
resolve: `gatsby-plugin-sitemap`,
options: {
// Exclude specific pages or groups of pages using glob parameters
// See: https://github.com/isaacs/minimatch
// The example below will exclude the single `path/to/page` and all routes beginning with `category`
output: '/',
excludes: [`/legal/*`,`/gracias`],
query: `
{
site {
siteMetadata {
siteUrl
}
buildTime(formatString: "YYYY-MM-DD")
}
allSitePage {
nodes {
path
}
}
allMarkdownRemark(filter: {frontmatter: {path: {regex: "/blog/"}}}) {
nodes {
frontmatter {
path
date
}
}
}
}
`,
resolvePages: ({
allSitePage: { nodes: allPages },
allMarkdownRemark: { nodes: allPosts },
}) => {
const pathToDateMap = {};
allPosts.map(post => {
pathToDateMap [post.frontmatter.path] = { date: post.frontmatter.date };
});
const pages = allPages.map(page => {
return { ...page, ...pathToDateMap [page.path] };//what does this line of code do???
});
return pages;
},
serialize: ({ path, date, buildTime }) => {
let entry = {
url: path,
changefreq: 'monthly',
priority: 0.5,
};
if (date) {
entry.priority = 0.7;
entry.lastmod = date;
} else {
entry.lastmod = buildtime;
}
return entry;
}
}
}
For your knowledge both develop and build are succesful, the sitemap is generated as sitemap-index and sitemap-0.xml, and the output is there but no page has lastmod on it.
Thank you all for your help,
With this:
return { ...page, ...pathToDateMap [page.path] };
You are merging objects using the spread operator (...). So, you are returning an object that is the result of all properties of the page and pathToDateMap(at page.path position).
For example:
let person = {
firstName: 'John',
lastName: 'Doe',
age: 25,
};
let job = {
jobTitle: 'Web developer',
location: 'USA'
};
let employee = {
...person,
...job
};
console.log(employee)
In the snippet above, employee is the result of merging person and job.
The lastmod parameter is not added by default unless your source has it (WordPress normally has) but you can follow this answer https://stackoverflow.com/a/70297982/5585371 to create your own.

to update multiple nested array using array filter not working in mongoose

I am using nodeJS with mongoldb 3.6.4. I have tried the Arrayfilter to update nested subdocument. But it is not updating the value. Here is the sample code I tried ( after incorporating the comments from Anthony Winzlet to make asyn Call)
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var DrugRefSchema = new Schema({
drugRefs: [{
refName: String,
drugs: [{
name: String,
drugType:String,
}]
}]
});
module.exports = mongoose.model('DrugRef', DrugRefSchema);
async function UpdateMedList () {
const out = await DrugRef.aggregate([
{ $unwind: '$drugRefs'},
{ $unwind: '$drugRefs.drugs'},
{ $project : { refName:'$drugRefs.refName', med:'$drugRefs.drugs.name',_id:0}},
{ $group: {_id: { med: '$med',refName:'$refName'}}},
{ $project : { med:'$_id.med', refName:'$_id.refName',_id:0}},
])
out.map(async(data) => {
var refName=data.refName;
var oldName=data.med;
var newName=oldName.trim();
const updateName = await DrugRef.update(
{ },
{ $set:{"drugRefs.$[i].drugs.$[j].name":newName}},
{ arrayFilters: [ { "i.refName": refName },{ "j.name": oldName }], "multi": true }
)
console.log("Orig:'"+oldName+"': to be updated:'"+newName+"':");
console.log("update Result:"+JSON.stringify(updateName));
})
}
and name is not getting changed still. pl help
Issue was with mongoose version. It was 4.3. When I upgraded to 5.x it started working.
Also when I upgraded with npm install mongoose with -g option it upgraded to 5.3.0 but my module mongoose was still pointing to 4.3. Then I had to install mongoose without -g also

Chrome Packaged App: Retrieving FileEntry in Dart from command line (LaunchData) parameter

Similarly to another post on this topic, I've been attempting to run my app from the command line with the file path of a local XML file so that my main.dart can parse this file in order to extract information relevant to program operation from it. I've been stumped as to how to appropriately access the FileEntry reference included in launchData -- the parameter for the onLaunched event.
Here's what I currently have:
manifest.json:
...
"permissions": [
"storage",
"fileSystem",
"*://*/*"
],
"file_handlers" : {
"any" : {
"types" : [ "*" ]
}
},
...
background.js:
chrome.app.runtime.onLaunched.addListener(function(launchData) {
chrome.app.window.create(
'htmlFile.html',
{...},
function(createdWindow) {
createdWindow.contentWindow.launchData = launchData;
});
});
At this point, I can't access launchData from main.dart because trying to do
FileEntry entry = (chrome.app.window.current().contentWindow.launchData as chrome.LaunchData).items.elementAt(0).entry;
to get the FileEntry results in an error for accessing launchData. I'm really confused about how I'm supposed to access the FileEntry that I want from my Dart code as a result.
I ended up with this as my solution:
manifest.json:
...
"file_handlers": {
"any": {
"extensions": [
"xml"
]
}
},
...
background.js:
chrome.app.runtime.onLaunched.addListener(function(launchData) {
chrome.app.window.create(
'htmlSource.html',
{
id: 'mainWindow',
state: "fullscreen"
},
function(createdWindow) {
if(launchData.items !== undefined) {
launchData.items[0].entry.file(
function(result) {
var reader = new FileReader();
var XML;
reader.onloadend = function(){
XML = reader.result;
chrome.storage.local.set({'XML': XML});
};
reader.readAsText(result);
},
function(){
console.log("Error reading XML file");
}
);
} else {
console.log("No file was detected.");
}
});
});
The dart code to retrieve the XML was simply:
String text = (await chrome.storage.local.get('XML'))['XML'];

Angular Resource update method with an array as a parameter

I have been googleing this for a few weeks with no real resolution.
I am sure someone will mark this a duplicate, but I am not sure it really is, maybe I am just being too specific, anyway here goes.
I am using angular in a node-webkit app that I am building. I have an api built in express and I am using MongoDB (#mongolab) with Mongoose for the DB.
I had this working fine as long as all of the data types were simple strings and numbers. but I had to restructure the data to use arrays and complex objects. After restructuring the data I was able to get post API calls to work fine, but I cannot get my PUT calls to work at all.
The data looks like this:
itemRoles was an array, but I thought it was throwing the error I am getting now, so I converted it back to a string.
itemStats is causing the problem. Angular is looking for an object, but itemStats is an array (I think anyway). itemStats used to be a string as well, but its easier to work with in my view if it is an array of objects with key:value pairs, which is why I altered it.
I should note I am new to MongoDB as well, first time using it.
{
"_id": {
"$oid": "55a10b9c7bb9ac5832d88bd8"
},
"itemRoles": "healer,dps",
"itemRating": 192,
"itemName": "Advanced Resolve Armoring 37",
"itemClass": "consular",
"itemLevel": 69,
"itemStats": [
{
"name": "Endurance",
"value": 104,
"_id": {
"$oid": "55a10b9c7bb9ac5832d88bda"
}
},
{
"name": "Willpower",
"value": 124,
"_id": {
"$oid": "55a10b9c7bb9ac5832d88bd9"
}
}
],
"__v": 0
}
The Mongoose Schema looks like this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//var stats = new Schema({
//name: String,
//value: Number
//});
var armoringSchema = new Schema({
itemType: String,
itemClass: String,
itemRoles: String,
itemLevel: Number,
itemName: String,
itemRating: Number,
itemStats: [{ name:String, value:Number}]
});
module.exports = mongoose.model('Armor', armoringSchema);
Express API Route:
/ on routes that end in /armors/:id
// ----------------------------------------------------
router.route('/armors/:id')
// get method omitted
// update the armoring with specified id (accessed at PUT http://localhost:8080/api/armors/:id)
.put(function(req, res) {
// use our armor model to find the armor we want
Armoring.findById({_id: req.params.id}, function(err, armor) {
if (err) {
return res.send(err);
}
for(prop in req.body) {
armor[prop] = req.body[prop];
}
// save the armor
armor.save(function(err) {
if (err) {
return res.send(err);
}
res.json({success:true, message: 'Armor updated!' });
});
});
})
Resource Factory:
swtorGear.factory('armoringFactory', ['$resource', function ($resource) {
return $resource('http://localhost:8080/api/armors/:id', {}, {
update: { method: 'PUT', params: {id: '#_id'}},
delete: { method: 'DELETE', headers: {'Content-type': 'application/json'}, params: {id: '#_id'}}
});
}]);
Route for editing:
.when('/edit/armor/id/:id', {
templateUrl: 'views/modelViews/newArmor.html',
controller: 'editArmorCtrl',
resolve: {
armoring: ['$route', 'armoringFactory', function($route, armoringFactory){
return armoringFactory.get({ id: $route.current.params.id}).$promise;
}]
}
})
Contoller (just the save method, the first part of the controller populates the form with existing data):
$scope.save = function(id) {
$scope.armor.itemStats = [
$scope.armor.stats1,
$scope.armor.stats2
];
$scope.armor.itemRoles = '';
if($scope.armor.role.tank) {
$scope.armor.itemRoles += 'tank';
}
if($scope.armor.role.healer) {
if($scope.armor.itemRoles != '') {
$scope.armor.itemRoles += ',healer';
} else {
$scope.armor.itemRoles += 'healer';
}
}
if($scope.armor.role.dps) {
if($scope.armor.itemRoles != '') {
$scope.armor.itemRoles += ',dps';
} else {
$scope.armor.itemRoles += 'dps';
}
}
console.log($scope.armor);
$scope.armor.$update(id)
.then(function(resp) {
if(resp.success) {
var message = resp.message;
Flash.create('success', message, 'item-success');
$scope.armors = armoringFactory.query();
} else {
var message = resp.message;
Flash.create('success', message, 'item-success');
}
});
}
Formatted data being sent via PUT method (from console.log($scope.armor) ):
Error on save:
I haven't seen nesting schemas in the way that you're doing it. Here's something to try (hard to say if this is it for sure, there's a lot going on):
var armoringSchema = new Schema({
itemType: String,
itemClass: String,
itemRoles: String,
itemLevel: Number,
itemName: String,
itemRating: Number,
itemStats: [{
name: String,
value: Number
}]
});
Also we need to pass in an object to $update instead of just a number. Change $scope.armor.$update(id) to $scope.armor.$update({id: id}).

Batch Update an array in mongoose object

My Schema is as below. A student can participate in any no. of events.and each Event can have any number of students.
Student{
name:String,
age:Number,
.
.
.,
events:{
type:
[
{type:Schema.ObjectId,
ref:'Event'}
]
}
}
Event{
title:String,
desc:String,
eventDate:Date,
participants:{
type:
[{
student: {type:Schema.ObjectId,
ref:'Student'},
status : String
}]
}
}
My requirement:
Every time,I create an event, I need to push all the participants of that event inside event object. and in turn, tag the event reference inside all the participants.
My code is
function handleTeamParticipants(eventObj, participants) {
Student
.find({
$or: [{
_id: participants[0].student._id
}, {
_id: participants[1].student._id
}]
})
.populate('events events.participants events.participants.student')
.exec(function(err, students) {
var studentLength = students.length,
result = [];
var saveAll = function() {
var doc = students.pop();
Student.populate(doc, {
path: 'events.participants.student',
model: 'Student'
}, function(err, student) {
student.events.push(eventObj);
student.save(function(err, saved) {
if (err) next(err); //handle error
result.push(saved);
if (--studentLength) saveAll();
else // all saved here
{
return res.status(200).send(eventObj);
}
});
});
};
saveAll();
});
}
This code is working.
So, this way, I get only the first two participants updated and in turn added to eventobj. But I want the find query to select all the participants.student._id
Please let me know the easy way to do it.
Thanks.
I used lodash method pluck.
lodash.pluck(< arrayObj >,< attribute >);
will give the list of attribute values in the arrayObj.
studentList = lodash.pluck(pariticipants,"student");
studentIdList = lodash.pluck(studentList,"_id");

Resources