No updating collection in mongodb - mongodb

I use 0.6.4. Don't work Collection.update(t.data._id, { $set: { name: e.currentTarget.value}}); Session.set("edit-" + t.data._id, false);.

I'd recommend using jQuery to extract the value: $(e.currentTarget).val(). Also, assuming the person template is rendered from an {{#each people}}, you could probably just do this._id, but it's hard to tell without seeing the templates.
People.update(this._id, { $set: { name: $(e.currentTarget).val()}});
I'd also suggest logging these values to the console before the update to make sure the callback is getting executed and that you are reading the right values.

Related

Mutation cache update not working with vue-apollo and Hasura

I'm completely new to these technologies, and am having trouble wrapping my head around it, so bear with me. So, my situation is that I've deployed Hasura on Heroku and have added some data, and am now trying to implement some functionality where I can add and edit certain rows of a table. Specifically I've been following this from Hasura, and this from vue-apollo.
I've implemented the adding and editing (which works), and now want to also reflect this in the table, by using the update property of the mutation and updating the cache. Unfortunately, this is where I get lost. I'll paste some of my code below to make my problem more clear:
The mutation for adding a player (ADD_PLAYER_MUTATION) (same as the one in Hasura's documentation linked above):
mutation addPlayer($objects: [players_insert_input!]!) {
insert_players(objects: $objects) {
returning {
id
name
}
}
}
The code for the mutation in the .vue file
addPlayer(player, currentTimestamp) {
this.$apollo.mutate({
mutation: PLAYER_ADD_MUTATION,
variables: {
objects: [
{
name: player.name,
team_id: player.team.id,
created_at: currentTimestamp,
updated_at: currentTimestamp,
role_id: player.role.id,
first_name: player.first_name,
last_name: player.last_name
}
]
},
update: (store, { data: { addPlayer } }) => {
const data = store.readQuery({
query: PLAYERS
});
console.log(data);
console.log(addPlayer);
data.players.push(addPlayer);
store.writeQuery({ query: PLAYERS, data });
}
});
},
I don't really get the update part of the mutation. In most examples the { data: { x } } bit uses the function's name in the place of x, and so I did that as well, even though I don't really get why (it's pretty confusing to me at least). When logging data the array of players is logged, but when logging addPlayer undefined is logged.
I'm probably doing something wrong that is very simple for others, but I'm obviously not sure what. Maybe the mutation isn't returning the correct thing (although I'd assume it wouldn't log undefined in that case), or maybe isn't returning anything at all. It's especially confusing since the player is actually added to the database, so it's just the update part that isn't working - plus, most of the guides / tutorials show the same thing without really much explanation.
Okay, so for anyone as stupid as me, here's basically what I was doing wrong:
Instead of addPlayer in update: (store, { data: { addPlayer } }), it should be whatever the name of the mutation is, so in this case insert_players.
By default a mutation response from Hasura has a returning field, which is a list, and so the added player is the first element in the list, so you can get it like so: const addedPlayer = insert_players.returning[0];
I didn't want to just delete my question after realising what was wrong shortly after posting it, in case this is useful to other people like me, and so I'll leave it up.

MongoDB - Update field with reference of another document

I would like if is possible to update a field of all documents in a collection with a reference to another document. I have tried to do this with the code below:
var project = db.Project.find({slug:"engine"});
db.Activity.update({}, {$set:{'project':DBRef("Project", project._id, "mydb")}});
When I look at the Activity documents, in the "project" field, the result is:
{
_id: ObjectId("..."),
"project": DBRef("Project", undefined, "mydb")
}
Is there a way to do this correctly?
Thanks in advance.
Seems to me you're having a promise callback problem. You can solve it in two ways:
Option one: Put the function depending of your data return inside a callback of the first function, for example:
db.Project.find({slug:"engine"}, function(error, data) {
db.activity.update(...data.Id...);
});
Option two: Wait for the return of the find to be completed:
var project = db.Project.find({slug:"engine"});
project.then(function(error,data) {
db.activity.update(...project.Id...);
});
Both should work. The problem is that when you make the first call, it returns a promise, not the value itself. If you are making confusion on this topic, you can take a look at:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Hope my answer helped you.

after using $and query, the results aren't render on DOM

I am building some little log reporting with meteor.
have a dead simple table, that should contain all the data that received from the external mongodb server.
the html:
<tbody>
{{#each impressions}}
<tr>
{{> impression}}
</tr>
{{/each}}
</tbody>
js :
Meteor.subscribe('impressions');
...
...
Template.logResults.helpers({
'impressions': function() {
var sTs = Router.current().params.fromTs;
var eTs = Router.current().params.toTs;
return Impressions.find({});
}
});
So far, so good. BUT, when I am changing the query to this one :
Impressions.find({
$and: [{
ts: {
$gte: sTs
}
}, {
ts: {
$lte: eTs
}
}]
});
The results aren't displayed on the HTML DOM,
I tried to debug that, and created a console.log of this exact query,
and surprisingly all the correct results return successfully to the console.
screenshot attached.
I am probably doing something wrong, maybe with publish/subscribe thing.
help someone?
Thanks.
P.S. I removed the insecure and auto-publish,
have this code on the server folder
Meteor.publish('impressions', function() {
return Impressions.find();
});
and this code on the main lib folder
Impressions = new Mongo.Collection("banners");
enter image description here
The router stores the parameters for the current route as strings (which makes sense because URLs are strings), so you need to explicitly convert the values to integers before querying the database. Give something like this a try:
var sTs = Number(Router.current().params.fromTs);
var eTs = Number(Router.current().params.toTs);
Notes:
parseInt or parseFloat may be a better choice depending on the nature of your input. See this question for more details.
You could do the type conversion in the router itself and pass the values in the data context to the helpers. See this section of the iron router guide.
I suspect it worked when you typed it into the console because you used numbers instead of strings. E.g. ts: {$gte: 123} instead of ts: {$gte: '123'}.

Using typeahead.js to return list of Facebook friends

I am using the Facebook Graph API to return a list of Facebook friends. I then want to run the returned JSON into Typeahead.js as follows:
$(document).ready(function () {
$('input.friends').typeahead({
name: 'friends',
prefetch: 'https://graph.facebook.com/me/friends?access_token=<?php echo $access_token;?>',
ttl: 0,
template: [
'<p class="name-tag">{{name}}</p>'
].join(''),
engine: Hogan
});
});
My corresponding HTML is as follows:
<input class="friends typeahead" type="text" placeholder="Start typing" id="friends">
But nothing is being returned using the prefetch (with hardcoded, local values, no problem). I am not seeing any errors in the console regarding cross-domain issues.
I am fairly sure this is because Typeahead hasn't been told how to handle the JSON structure, but I am unsure how to achieve this. I have tried implementing the templating system Hogan (which I will admit to being unfamiliar with) but this has not helped.
Any ideas much appreciated.
Many thanks
You need to either use valueKey if the result is a simple list of objects, from which you want to use a specific key as your values, or alternatively use a filter: to convert the result into a flat list of suggestions.
In your case, the response is a object with a data member that is a list of name, id pairs. You can have filter() be a function that returns response.data (to extract the list from the data member), and then set valueKey to name.
Thanks Nitzan.
My code snippet currently looks like:
valueKey: 'name',
remote: {
url: 'https://graph.facebook.com/me/friends?access_token=<?php echo $access_token;?>',
filter: function (response) {
return response.data;
},
},
template: [
'<p>{{name}}</p>',
].join(''),
engine: Hogan
Which returns ALL the names in the JSON at once, no matter what is in the input box.
Is this a problem with the filter or something else?
Solution below. Remember to include Hogan if you're using that as your templating engine, as I have done:
$.get('https://graph.facebook.com/me/friends?access_token=<?php echo $access_token;?>', function(server_data){
var rt = {};
for (var i in server_data.data)
rt[server_data.data[i].id] = {name:server_data.data[i].name, id:server_data.data[i].id},
//rt.push({name:server_data.data[i].name})
console.log(rt)
$('input.friends').typeahead({
limit: 10,
name: 'friends',
valueKey: 'name',
local:rt,
template: [
'{{id}}',
].join(''),
engine: Hogan
});
})

Update values in array in MongoDB

I'm trying to come up with a way to update the values in an array of objects in mongo. I have a collection which looks like
[
{ CourseName: '',
Sessions: [
{
_id: null, //oops I didn't set this in the import
Name: 'blah',
Location: 'moon'
}]
}
]
Now I need to set the _id field. I tried the documented approach of doing
db.Course.update({'Sessions._id': null}, {$set:{'Sessions.$._id': ObjectId()}}, false, true)
But I ran into this bug http://jira.mongodb.org/browse/SERVER-1055 which meant that I couldn't do it. Is there some syntax which will allow me just to itterate over the collection and update each record by hand? I tried a few things like
db.Course.find().forEach(
function(course)
{
course.Sessions.forEach(function(session)
{
session._id=ObjectId();
course.Save(session); //Don't know how to save a single object
});
});
but they didn't work. I'm looking for some way to just update that value in each session.
I think what you want is:
db.Course.find().forEach(
function(course)
{
course.Sessions.forEach(function(session)
{
session._id=ObjectId();
});
db.Course.save(course);
});
However, you can run into problems saving stuff into a collection you're in the middle of iterating over, so I'd suggest loading a bunch of documents into an array, processing them, loading another batch, etc.