Accessing minimongo from template helper meteor / mongodb - javascript

I am trying to access my Products collection in Minimongo in the html page. When I am in my browser console, I am able to type Products.findOne(); and it will return a product.
However, when I try to return a product from my template helper, I get undefined. Thoughts anyone?
Template.Tires.onRendered(function() {
console.log(Products.findOne());
//after I return a product item, I need to modify its properties manually after it has loaded into the client
});

Simple answer:
Do whatever modification you need to do on the collection within the helper function and then return a JS object. For instance if you collection looks something like this:
SomeColleciton
_id
type: String
birthday:
type: Date
firstname:
type: String
lastname:
type: String
timezone:
type: Integer
you can do the following to transform it
Template.Tires.helpers({
user: function(userId) {
var u = SomeCollection.findOne(userId);
var age = calcAge(u.birthday);
var ifworkinghour = calcifworkinghour(u.timezone);
return {name: u.firstname + ' ' + u.lastname, age: age, workinghour: ifworkinghour}
});

Related

Parse JSON Object from MongoDB GET

I have a ReactApp with a MongoDB based on local events here in my city. The current schema looks like this.
const eventSchema = mongoose.Schema({
start: String,
end: String,
name: String,
loc: { // Reference: https://mongoosejs.com/docs/geojson.html
type: {
type: String,
enum: ['Point']
},
coordinates: {
type: [Number]
}
},
web: String,
desc: String
});
I have an event button where I press, it gets the data from the DB and renders it to the HTML Page
callbackGetData() {
fetch('/api')
.then(resp => {
console.log(resp);
return resp.json();
})
.then(jdat => {
console.log(jdat);
this.setState({ data: JSON.stringify(jdat)}); // Print to debug area.
// todo: Update marker on the map?
});
}
when printed on the screen, this the results from the JSON objects that are stored in the database
[{"loc":{"coordinates":[-122.698687,45.526974],"type":"Point"},"_id":"5e5c3cde56138449ec49905f","start":".","end":".","name":"Portland Dining Month","web":".","desc":".","__v":0},
{"loc":{"coordinates":[-122.680712,45.509871],"type":"Point"},"_id":"5e5c3cde56138449ec499060","start":".","end":".","name":"Test event #PSU","web":".","desc":".","__v":0},
{"loc":{"coordinates":[-122.674043,45.481716],"type":"Point"},"_id":"5e5c3cde56138449ec499057","start":".","end":".","name":"Transgender Clients: Assessment and Planning for Gender-affirming Medical Procedures","web":".","desc":".","__v":0}]
If I try to go and print it with
console.log(jdat);
this.setState({ data: JSON.stringify(jdat.name)});
It says that it undefined. How can I go about printing out just the individual names and location coordinates and storing them in a variable I can use elsewhere in the file? Thanks
Looks like you have a array of data coming from database. so trying jdat.name will not work. You need to iterate over the array.
try the following code.Hope you are looking for the same
var jdat = [{"loc":{"coordinates":[-122.698687,45.526974],"type":"Point"},"_id":"5e5c3cde56138449ec49905f","start":".","end":".","name":"Portland Dining Month","web":".","desc":".","__v":0},
{"loc":{"coordinates":[-122.680712,45.509871],"type":"Point"},"_id":"5e5c3cde56138449ec499060","start":".","end":".","name":"Test event #PSU","web":".","desc":".","__v":0},
{"loc":{"coordinates":[-122.674043,45.481716],"type":"Point"},"_id":"5e5c3cde56138449ec499057","start":".","end":".","name":"Transgender Clients: Assessment and Planning for Gender-affirming Medical Procedures","web":".","desc":".","__v":0}]
jdat.forEach(item =>{
console.log("Name : ",item.name)
console.log("Location Coordinates : ",item.loc.coordinates)
})

Nested Firestore queries not returning results to primary query

I've got two Firestore collections, /projects and /tasks. The /tasks collection contains a reference field to a id field in the /projects collection. In typescript I've extended my the task class with a projectname member. So when querying the /tasks collection I need to return the projectname as well.
My current code is using valueChanges(), my first attempt was made using snapshotChanges().
Currently my code looks like this:
this.xtasks = this.tasksCollection.valueChanges().pipe(
map(values => values.map(data => {
return {
created: data.created,
createdby: data.createdby,
description: data.description,
due: data.due,
lastmodified: data.lastmodified,
lastmodifiedby: data.lastmodifiedby,
project: data.project, // i.e. /projects/<guid>
sort: data.sort,
state: data.state,
title: data.title,
uid: data.uid,
projectname: this.projectService.getProjectStringField(data.project.replace('/projects/', ''), 'name') // supposed to retrive name of a project by project guid
};
})
)
);
But when the pipe returns the result the projectname is empty. I've tried looking into Promise but I'm not able to get it to return a value for projectname.
In the snippet all /tasks field are represented in the data object but I want to fetch the project name as well.

Upsert data with a dynamic field name

I just try to do something simple with Mongo but it doesn't work:
I want to upsert datas in an object like: module.xxx.yyy then I tried many things like :
UsersRights.upsert({
condoId: condoId,
userId: manager._id,
}, {
condoId: condoId,
userId: manager._id,
module: {
[defaultRight.xxx] : {
[defaultRight.yyy] : defaultRight.default
}
}
});
but when I want to add a new xxx or a new yyy, it will erase and replace the entire module object and not only add a new key.
I also tried this :
UsersRights.upsert({
condoId: condoId,
userId: manager._id,
}, {
condoId: condoId,
userId: manager._id,
["module." + defaultRight.module + "." + defaultRight.right] : defaultRight.default,
});
but the server show me an error like: MinimongoError: Key module.xxx.yyy must not contain '.'
You need to use the following form:
YourCollection.upsert({
_id: id, (can be other selectors as well)
}, {
$set: setter
});
Setter is an object you create before and should have the following form:
const setter = {};
setter[`${#1Level}.${#2Level}`] = data;
Where #1Level & #2Level are vars naming the fields you want to modify or to add.

Pass list of items from $.get() to MVC controller

My controller Action method looks like the below:
[HttpGet]
[Route("ShowModal")]
public Task<IActionResult> GetDetails(int id, string name, IEnumerable<Employee> employees)
{
//create a model
//Some business logic codes
return PartialView("_Partial.cshtml", model);
}
I need to call the above Action Method from jQuery's $.get() method on a button click, capture the partial view returned as HTML, and show it in a Bootstrap popup.
I am not able to pass the IEnumerable<Employee> from the jQuery method, it is always null, whatever I try.
Below is the JS code:
<a class="btn btn-primary" onclick="ShowModal();" data-keyboard="true" data-toggle="modal">ShowModal</a>
<div class="modal fade" id="divShowModalDialog" role="dialog" tabindex="-1">
<div class="modal-body" id="divShowModalBody">
</div>
</div>
function ShowModal()
{
var list = [{ Id: 101, Gender: 'MALE' }, { Id: 102, Gender: 'FEMALE' }];
list = JSON.stringify(list);
var data = { 'id': 999, 'name': 'JAMES', 'employees': list };
$.get('/Area1/Controller1/ShowModal', data)
.done(function (response) {
if (response != undefined) {
$('#divShowModalBody').html(response);
$('#divShowModalDialog').modal(
{
backdrop: 'static',
keyboard: true,
});
}
})
.fail(function (xhr) {
console.log(xhr);
})
}
I get the id and name parameter in the Action method, but the list is always empty. I have tried after removing JSON.stringify() as well, but it doesn't work.
I know I'm missing a trivial thing, please help.
First, you should be using [HttpPost] on your controller action and not [HttpGet], and of course you'll need to use post from jQuery which is using $.post() and that is because 'POST' is the correct - but not the only - HTTP verb to actually post data to the server side.
Second, you shouldn't stringify your employees list before you put it in your data javascript object that you are sending.
so, list = JSON.stringify(list); and just straight away go
var data = { 'id': 999, 'name': 'JAMES', 'employees': list };
You also might need to provide the dataType using $.post(url,data,onsucess,dataType) check documentation in the link above.
Last, on your action method remove IEnumerable<T> and replace it with a concrete collection type like List<T> because the JSON serializer will need to know which type of collection to instantiate at binding time.
Actually you can achieve it without changing it to POST by using $.ajax()
Use a dictionary object instead of IEnumerable in action method
public ActionResult GetDetails(int id, string name, Dictionary<int,string> employees)
{
And then in the script
var list = [{ Id: 101, Gender: 'MALE' }, { Id: 102, Gender: 'FEMALE' }];
var data = { id: 999, name: 'JAMES', employees: list };
debugger;
$.ajax({
url: '/Home/GetDetails',
type: "GET",
data :data,
contentType: "application/json",
dataType: "json"
});
I was replying to your comment but decided it would be easier to demonstrate my point as an answer.
To answer your question, no I am not sure. But thats why I asked you to try it first, it seems logical as you are passing a list and not IEnumerable to your function.
Also, depending on what your Employee class looks like, you should try this: (you need a constructor in your Employee class for this)
List<Employee> list = new List<Employee>();
list.Add(new Employee(101, 'MALE'));
list.Add(new Employee(102, 'FEMALE'));
var data = { 'id': 999, 'name': 'JAMES', 'employees': list };
...
Update
I realize why I'm wrong, I kept thinking in C# terms. Json.stringify() returns a json style string (which C# just sees as a string), so your public Task GetDetails(int id, string name, IEnumerable employees) should be public Task GetDetails(int id, string name, string employees) and then in C#, you need to parse the JSON string. A helpful link:
How can I parse JSON with C#?

Saving string when field is nested object

My Item Schema:
new Schema({
name: {
ka: String,
en: String
}
});
When doing like this:
Item.findOne({}, function(err, item){
item.name = 'wrongtype';
item.save();
});
item's name property is saved to database, despite of fact that name is described as object in schema. Validation is not working. Can you suggest solution? Or explain if it's correct behaviour

Categories