Remove property in Meteor user - meteor

I have a Meteor app where I have users who can select favorite cards etc. I store favorite cards in Meteor.user().profile.favorites[]. This is an array with cards (objects). I can't seem to find a way how to remove one from this array.

$pull is used to remove an item from an array, you need to give it the exact document.
Users.update(id, $pull : { profile : { favorites : { favorite } } });

Related

What is 'Template.instance().view'?

I read [Template.instance().view]1 at Blaze docs.
Also I read Blaze.view().
I even saw the view object in the console log.
But I can't understand.
Could anyone explain it more intuitively and smoothly, please? :)
If you want to understand Views more deeply, you need to understand the relationship between Templates, TemplateInstances, and Views. Views are just reactive parts of the DOM. Template instances contain one View, but templates can create more views through functions that create renderable content like Blaze.with ({{#with}}) or Blaze.if ({{#if}}). These "child" views will will then store a parent pointer, which you can use to reconstruct the View tree.
What might help your understanding is playing around with how Templates and Views interact in Chrome tools. You can find a template instance by using any DOM element. Here is an example to get you started:
templateInstance = Blaze.findTemplate($('<some component in dom>')[0])
view = templateInstance.view
You can extend Blaze to contain findTemplate like this:
Blaze.findTemplate = function(elementOrView) {
if(elementOrView == undefined) {
return;
}
let view = Object.getPrototypeOf(elementOrView) === Blaze.View.prototype
? elementOrView
: Blaze.getView(elementOrView);
while (view && view.templateInstance === undefined) {
view = view.originalParentView || view.parentView;
}
if (!view) {
return;
}
return Tracker.nonreactive(() => view.templateInstance());
};

Displaying dynamic content in Meteor using Dynamic Templates

I've read through the (somewhat sparse) documentation on Dynamic Templates but am still having trouble displaying dynamic content on a user dashboard based on a particular field.
My Meteor.users collection includes a status field and I want to return different content based on this status.
So, for example , if the user has a status of ‘current’, they would see the 'currentUser' template.
I’ve been using a dynamic template helper (but have also considered using template helper arguments which may still be the way to go) but it isn’t showing a different template for users with different statuses.
{{> Template.dynamic template=userStatus}}
And the helper returns a string to align with the required template as required
userStatus: function () {
if (Meteor.users.find({_id:Meteor.userId(), status: 'active'})){
return 'isCurrent'
}
else if (Meteor.users.find({_id:Meteor.userId(), status: ‘isIdle'})) {
return 'isIdle'
} else {
return ‘genericContent'
}
}
There may be much better ways to go about this but it seems a pretty common use case.
The few examples I've seen use Sessions or a click event but I’d rather use the cursor if possible. Does this mean what I’m missing is the re-computation to make it properly reactive? Or something else incredibly obvious that I’ve overlooked.
There is a shortcut for getting the current user object, Meteor.user(). I suggest you get this object and then check the value of the status.
userStatus: function () {
if(Meteor.user()) {
if (Meteor.user().status === 'active') {
return 'currentUserTemplate'; // this should be the template name
} else if (Meteor.user().status === 'isIdle') {
return 'idleUserTemplate'; // this should be the template name
}
} else {
return ‘notLoggedInTemplate'; // this should be the template name
}
}
Ended up using this approach discussed on the Meteor forums which seems a bit cleaner.
{{> Template.dynamic template=getTemplateName}}
And the helper then becomes:
getTemplateName: function() {
return "statusTemplate" + Meteor.user().status;
},
Which means you can then use template names based on the status:
<template name="statusTemplateActive">
Content for active users
</template>
(though keep in mind that Template helpers don't like hyphens and the data context needs to be set correctly)

Get Dropdown Value in Meteor Js?

I did one sample Searchapp using meteor add sebdah:autocompletion package.When ever given inputs it shows drop down list.In this list how to get selected value as shown below code:
Js Code :
Friends = new Meteor.Collection('friends');
if (Meteor.isClient) {
/**
* Template - search
*/
Template.search.rendered = function () {
AutoCompletion.enableLogging = true;
var res = AutoCompletion.init("input#searchBox");
console.log("res :"+res);
}
Template.search.events = {
'keyup input#searchBox': function (e,t) {
AutoCompletion.autocomplete({
element: 'input#searchBox', // DOM identifier for the element
collection: Friends, // MeteorJS collection object
field: 'name', // Document field name to search for
limit: 0, // Max number of elements to show
sort: {name: 1}
});
}
}
}
I didn't get any idea about this.So please suggest me how to get selected drop down list values?
AutoCompletion package doesn't give any good API to read value on select. Instead you need to manually read the value of input#searchBox.
Please take a look at source code.
I would recommend to implement searching in your meteor app using Arunoda's approach : https://meteorhacks.com/implementing-an-instant-search-solution-with-meteor.html

AngularFire update single object

How to update a single object within node.
{
foo:
{
title: 'hello world',
time: '1000'
}
}
As above, I just want update title.
$firebase(new Firebase(ref).child('foo')).$save(); will update the entire node. Also tried $save('title') but not work.
The reason I just want to update a single object, because some of the ng-model doesn't need to update to firebase.
Heres an example setting the title to "whatever"
$firebase(new Firebase(ref)).$child('foo').$child('title').$set("whatever")
I have recently been working with angularfire and firebase. I am not sure if this is a fix but i dont think you dont need to explicitly select the item property you want to update when you are using the $save() method.
For instance, in my use case i was selecting a user and had an init function that got that whole object
html
<ul ng-repeat="user in vm.users>
<button ng-click="vm.updateUserInit(user)">Edit</button>
</ul>
This then opened up the update form with the users properties. In the controller i took that user and assigned it into a $firebaseObject.
controller
var selectedUser;
vm.updateUserInit = function (user) {
var ref = new Firebase("https://<foo>.firebaseio.com/users/" + user.$id);
selectedUser = $firebaseObject(ref);
}
It justs puts the user into a firebase object as the variable selectedUser to use in the $save.
Then when the user updates the details
html
<button type="button" ng-click="vm.updateUserDetails()">Update User Details</button>
the function already has the selected user as an object to use and anything added will be updated. Anything omitted will not.
controller
vm.updateUserDetails = function () {
selectedUser.firstName = vm.firstName;
selectedUser.$save();
}
The selectedUser.$save(); changes only the first name even though the user has 6 other properties
Not sure if this helps, trying to wrap my head around all of this as well. Check out valcon if you dont already have it. Really nice extension on the chrome inspector for firebase
UPDATE FOR ANGULARFIRE 2
if you create a service for your calls , which could serve all update calls
constructor(private db: AngularFireDatabase) {}
update(fbPath: string, data: any) {
return this.db.object(fbPath).update(data);
}
And then in the page component
this.api.update(`foo`, ({ title: 'foo Title' }) );
Much simpler

How to update using angularFireCollection which items not exist previously

I have this parent node with text and I want to add a media into the parent node also if the text is changed will update as well.
{
parent: {
text: 'this is content'
}
}
The media value from a third-party callback. How to pass it to update()? I tried {media: callbackVal} but not working.
$scope.parent = angularFireCollection(firebaseRef.child('parent'));
$scope.parent.update(What_to_do_here, function(error){
//something...
});
UPDATE
Maybe my question is not clear enough.
In Firebase JS, we can do this to update or insert media into the node.
new Firebase(firebaseRef).update({ media: 'value'} );
How to do this in `angularFireCollection ?
Check out the annotated AngularFire source: http://angularfire.com/src/angularFire.html#section-38
It looks like AngularFireCollection.update() takes a key/item and a callback function. So you need to edit the entry you want to update directly in your AngularFireCollection, (e.g. $scope.parent.getByName('media').value = 'alligator scrimshaw') and then call $scope.parent.update($scope.parent.getByName('media'), function(err) { ... }).
NOTE: One rather confusing thing (which maybe I am misunderstanding) is that there doesn't seem to be a way to add data to an AngularFireCollection by id. So if media doesn't already exist in your Firebase, $scope.parent.getByName('media') will return undefined. For this reason, if you don't need explicit syncing, and implicit syncing is fine, I would use an AngularFire object instead of an AngularFireCollection.

Resources