Why am I getting wrappedPointCut instead of the data? - node.js

I have 3 tiers of nested objects stored in mongoDB.
The first tier shows the name like it is supposed to, the second as well.
But when it goes in to the third tier it shows the text:"wrappedPointCut"
Why is this? and What does wrapedPointCut mean??
I have a handlebars test code like this:
{{#each tierOne}}
<h2>{{ this.tierOneName }}</h2>
{{#each tierTwo}}
<h2>{{ this.tierTwoName }}</h2>
{{#each tierThree}}
<h2>{{ this.tierThreeName }}</h2>
{{/each}}
{{/each}}
{{/each}}
</div>
When iterating through the nested objects in JS I get the correct output in console. Also if I add 4 objects to the third tier I get 4 headers that read:"wrapedPointCut". This must mean it knows that there is data here.
this is the mongoDB structure:
this is the Tier 3:
var TierThree = new mongoose.Schema({
tierThreeName : {
type: String
}
});
this is the Tier 2:
var TierTwo = new mongoose.Schema({
tierTwoName : {
type: String
},
tierThree : [TierThree]
});
this is the Tier 1:
var TierOne = mongoose.Schema({
tierOneName : {
type: String,
index:true
},
tierTwo: [TierTwo]
});
Here is the function that exports the third tier to monngoDB:
module.exports.createTierThree = function(newTierThree, tierOne, tierTwoName , callback){
for (var i = 0; i < tierOne.tierTwo.length; i++) {
if(tierOne.tierTwo[i].tierTwoName == tierTwoName ){
tierOne.tierTwo[i].tierThree.push(newTierThree);
tierOne.tierTwo[i].save(function (err) {
if (!err) console.log('Success!');
});
}
}
};

The problem seemed to be that I'm doing something wrong when adding to database. If I add to the database using shell command everything is fine. So the problem now is to turn mongoDB shell command to JS.

Related

Display single item with Vue.js

I have a list of items where the title is a link to display a detailed view of the item. Click the title and it correctly goes to url + Id. In the Vue tolls the detail page retrieves the item with matching ID but as and array not an object and the template does not display any properties - what am I missing?
<script>
import axios from "axios";
export default {
name: "Report",
data() {
return {
report: {}
};
},
mounted: function() {
this.getReport();
},
methods: {
getReport() {
let uri = "http://localhost:5000/api/reports/" + this.$route.params.id;
axios.get(uri).then(response => {
this.report = response.data;
});
}
}
};
</script>
The template is so
<template>
<v-content>
<h1>report detail page</h1>
<p>content will go here</p>-
<h3>{{ report.month }}</h3>
<pre>{{ report._id }}</pre>
</v-content>
</template>
any comments appreciated
url + Id
It sounds like your issue is that you are receiving an array not an object.
You can pull out objects encapsulated inside arrays easily.
For example, if we had the following data:
var bus1 = {passengers:10, shift:1}
var busArr = [bus1]
which we can assert: busArr === [{passengers:10, shift:1}]
We could then pull out bus1 by referencing the index 0:
var bus1New = busArr[0]
If you want to avoid the data transformation and just output the structure you can consider a v-for in your template.
<p v-for="val in report">
_id: {{val._id}}
<br>
month: {{val.month}}
</p>

How to return array of query results (Node.js & MongoDB)

I'm trying to create an array of query results so that I can use that array to populate one of my handlebars pages. Each index in the array holds Comments with a unique attribute. I currently have it set up like this:
This kicks the whole thing off:
//num is determined above
Comment.getComments(num, function(err, comments){
if(err){
console.log("ERROR");
}
console.log(comments);
res.render('page-i-want-to-populate-with-comments', {com : comments});
});
The getComments function calls this (in my models/comment.js):
module.exports.getComments = function(num, callback){
var comArr = [];
for(var i = 0; i < num; i++){
var uniqueId = i;
Comment.find({commentId : uniqueId}, function(err, items){
comArr.push(items);
});
}
callback(comArr);
}
Ideally I would then go to page-i-want-to-populate-with-comments.handlebars and:
{{#each com}}
<div class="comment-wrapper>
{{#each this}}
<div class="comment">
<p>{{this.text}}</p> //the text contained in the comment
</div>
{{/each}}
</div>
{{/each}}
My points of failure now are that comArr is empty when sent through callback() which causes an error in the callback function.
I get that this is probably confusing but this is the best I can explain it. I've been stuck on this for a while so any advice would be appreciated.

How do I update a specific document from a form through mongoose?

Struggling with this problem because I'm missing some fundamentals I think, but after hours looking through the docs I think I need some help :)
I have a (simplified) collection as so:
const ExampleSchema= new Schema ({
Word: String,
Difficulty: String,
)};
Which I am succesfully displaying on a page as so:
<% ExampleSchemas.forEach(exampleschema=> { %>
<p><%= exampleschema.word %></p>
<p style="display: none" name="ExampleSchemaID" value="<%= ExampleSchema._id %>"</p>
<% }) %>
For each word I have a form below, I would like the user to be able to select easy, ok or hard and for this to set the value in the DB.
<form method="PUT">
<button formaction="/review/feedback/easy">Easy</button>
<button formaction="/review/feedback/ok">Ok</button>
<button formaction="/review/feedback/hard">Hard</button>
/form>
I have played around with a route like this to no avail
router.put("/review/feedback/easy", function (req,res){
var ID = req.body.ExampleSchemaID;
ExampleSchema.findByIdAndUpdate(
req.params.ExampleSchema._id,
req.Difficulty= easy);
The further issue is that I would like to display x number of these documents to the user, therefore I need a route that gets only that specific word.
router.put("/review/feedback/easy", function (req,res){
var ID = req.body.ExampleSchemaID;
ExampleSchema.findByIdAndUpdate({"_id": req.params.ExampleSchema._id},{"Difficulty": "3"});
but please not your difficulty is a number, so why not use a number instead:
const ExampleSchema= new Schema ({
Word: String,
Difficulty: Number,
)};
router.put("/review/feedback/easy", function (req,res){
var ID = req.body.ExampleSchemaID;
ExampleSchema.findByIdAndUpdate({"_id": req.params.ExampleSchema._id},{"Difficulty": 3});

How to return the corresponding image by id in a helper with CollectionFS?

I had real problems writing the title of this question. I am using gridfs for my storage, so the files are stored in my MongoDb. Now I have the following situation:
var imageStore = new FS.Store.GridFS('images', {});
Images = new FS.Collection('images', {
stores: [imageStore]
});
Test = new Meteor.Collection('test');
The Images are stored in Images and the "posts" are stored in test. Now when I upload an image, as I can't reference the image in my Test collection, I save the ._id for that image.
FS.Utility.eachFile(event, function (file)
{
var image = Images.insert(file, function (err, fileObj)
{
});
Test.insert({name: 'Test!', userId: '123123', image: image._id});
});
Now in my template, I want to show the name and the image. But what do I return in my helper? My template for a single post looks like this:
<li>
<h2>{{name}}</h2>
<img src="{{file.url}}" alt="" class="thumbnail" />
</li>
And the Helper function:
Tests: function ()
{
return each-test-with-their-image;
}
I imagined something like this, but it looks stupid as hell:
Tests: function ()
{
var tests = Test.find().fetch();
for(var i = 0; i < tests.length; i++)
{
tests[i].file = Images.findOne({_id: tests[i].image});
}
return tests;
}
But I feel that there must be a better way.
Rather than iterate over an array of results you can just get the url in a helper as each document is displayed. This is cleaner and you don't have to recompute the whole array as docs are added/removed/changed.
html:
<li>
<h2>{{name}}</h2>
<img src="{{url}}" alt="" class="thumbnail" />
</li>
js:
Template.myTemplate.helpers({
url: function(){
var queryImage = Images.findOne({_id: this.image});
return queryImage && queryImage.url();
}
});

Model is created but can't update with Express, Mongoose, and NodeJS

Alright so I'm having a problem with updating a model. I can create a Document and it works just fine but when I try to update, I get an error.
/Users/User/Sites/project/app.js:182
a.features.kids = req.body.a.features.kids;
^
TypeError: Cannot read property 'kids' of undefined
The model looks like this:
Affiliate = new Schema({
'name': String,
'address': String,
'features': {
'kids': { type: Boolean, default: false },
}
});
My form fields looks like this. They are used for both creating and updating with extra fields added for updating:
<input type="text" name="a[name]" id="a[name]" />
<input type="text" name="a[address]" id="a[address]" />
<input <% if (a.features.kids) { %>checked <% }; %>type="checkbox" name="a[features.kids]" id="a[features.kids]" />
Code for creating a new item. This works fine and all the information is added properly:
var a = new Affiliate(req.body.a);
a.save(function() {
res.redirect('/admin');
});
Broken code for updating an item:
Affiliate.findOne({ _id: req.params.id}, function(err, a) {
if (!a) return next(new NotFound('Affiliate not found'));
a.name = req.body.a.name;
a.address = req.body.a.address;
a.features.open_gym = req.body.a.features.kids;
a.save(function(err) {
res.redirect('/admin');
});
});
Yeah, I think the express bodyParser is probably not interpreting a[features.kids] the way you expect. You can access the field with req.body.a['features.kids'] since it's not interpreting that embedded period. Try naming your <input> a[features][kids] and see if that parses into the object structure you are expecting.

Resources