How do I delete objects within objects in Angular-Meteor? - arrays

NOTE: the following code and demo are extracted from a larger Meteor + Angular project.
I have the following functions to select and delete objects:
DEMO: http://plnkr.co/edit/Qi8nIPEd2aeXOzmVR6By?p=preview
$scope.selectParty = function(party) {
$scope.party = party;
$scope.type = party.type;
$scope.date = party.date;
}
$scope.deletParty = function(party) {
$scope.parties.remove(party);
}
$scope.selectOrganizer = function(organizer) {
$scope.organizer = organizer;
$scope.name = organizer.name;
$scope.title = organizer.title;
}
$scope.deletOrganizer = function(organizer) {
$scope.party.organizers.remove(organizer);
}
The Select action works on both Parties and Organizers as you can see in the demo, displaying the data in the table underneath.
The Delete action doesn't work. Although, let me point out that in my app, the one I have on my machine and currently working on in Meteor, the Delete action works splendidly on Parties, meaning the syntax "$scope.parties.remove(party)" works. But it doesn't work on the plnkr demo for some reason :(
My question is really about the Organizers Delete action, where I'm targeting an object (organizer) inside an array inside the selected object (party)… that one doesn't work. I'm wondering why, and what is the right syntax.
NOTE 2: I'm aware of Angular's splice and index but I can't use them here as I'm not simply working with Angular arrays but with database data in Meteor.
Thanks!

The organizer is a part of the party object and not a collection on it's own. So what you would need to do is remove the party from the object and then save the party object.
Note2 is incorrect. Unless you wrote your question and plunker wrong.

Related

How to reload a controller's angularJS call from a factory initiated by another controller

I am working on an angularJS project, a music player which can select an album and then play from a list of that album's songs. Everything is working except for that after playing a song from an album(album A) and then selecting another album (album B), when I try to select the previous/next song from a player bar, which is separated from the list, the previous album's (album A) songs play.
Clearly, something is not updating. I read here from a comment by Chev that factories run only once. So, I am thinking the problem might lie with my Songplayer controller(factory).
Here's the code:
AlbumController (the controller with the directive):
....
$rootscope.getAlbumId = $stateParams.getAlbumId;
this.albumData = Fixtures.getAlbum();
this.songPlayer = SongPlayer;
....
FixturesController (factory - serving the music files):
Fixtures.getAlbum = function(){
var chosenAlbum = $rootScope.getAlbumId
return chosenAlbum
....
};
SongPlayerController (factory - playing the music):
....
$rootScope.getAlbumId = $stateParams.getAlbumId;
var currentAlbum = Fixtures.getAlbum();
....
var getSongIndex = function(song){
return currentAlbum.songs.indexOf(song);
};
PlayerBarController:
code same as albumController
It seems the PlayerBarController is not registering the new album from the SongPlayer factory. I have researched and tried using $emit/$broadcast, $watch, various other callbacks, etc... I know the answer is everywhere I have looked but I simply do not have the angular skills yet to figure this out.
Incidentally, I figure my use of $rootScope is also pretty poor, so I am happy to receive advice on that. I used $rootscope and $stateparams in order to capture and register the album id and deliver it to the Fixtures controller.
I think the problem from 'this.albumData = Fixtures.getAlbum();'
You can try:
let albumData = Fixtures.getAlbum();
this.albumData.length = 0;
albumData.map(item => this.albumData.push(item));
I was able to get the PlayerBar controller to register the new album by using $watch. I simply wrapped the call I already had in a $watch function, and voila!
SongPlayer controller:
$rootScope.$watch('getAlbumId', function(album){
currentAlbum = Fixtures.getAlbum();
});

Listing Form Templates within another Controller view

I have a form_templates table and a forms table. They're connected by form_template_id. I want to be able to list the form_templates that have been created by title within a select.ctp file I have created within the Forms controller. Just wanting some direction on how to do this with cakephp?
At the moment I have the following code within my FormsController:
public function select()
{
$this->set('page_heading', 'Current Forms');
$contain = [];
$formTemplate = $this->FormTemplates->Forms->find('list', ['order' => 'title'])->where(['active'=>true]);
$forms = $this->paginate($this->Forms->FormTemplates);
$this->set(compact('forms', 'formTemplate'));
}
But I am getting a Call to a member function find() on null error.
Any help on how to tackle this would be greatly appreciated. I know it would be simple but I am new to cakephp.
In your FormsController only FormsTable is loaded automatically, and you are trying to access model that is not currently loaded:
$formTemplate = $this->FormTemplates->Forms->find(...
To get what you want, you should access associated FormTemplatesTable like this:
$formTemplate = $this->Forms->FormTemplates->find(...

How to insert an array of items in sqlite using angularjs and ionic

Is there a way to loop through linked values in angular to download a list of objects in a sqlite database. The tables am working on are modules, courses and library. So now when I download an item in courses it shows a linked reference to modules which tells me I have 4 or 2 link references based on that particular course then the second step comes in where that module has a linked reference to library the final table.
My question is how will i use a angular.forEach statement to loop through the first two tables and download the the course and the linked modules together.
modules.forEach(function(item) {
var lib ={};
lib._id = item._id;
lib.name = item.name;
lib.course = item.course;
lib.tests = item.tests;
lib.libraryItems = item.libraryItems;
console.log(lib);
return lib;
})
lib.forEach(function(item){
var no = {};
no._id = item._id;
no.TextContent = item.TextContent;
no.HtmlContentBase64 = item.HtmlContentBase64;
})
The code snippet I have above can list the items from the other table in my course table but only shows one instance of it. The second part of the code am still testing it now to see if am on the right track. Any assistance is greatly appreciated.

Overwrite properties in angular forEach

I imagine this is an easy thing to do, but I wasnt able to find the information I was looking for through google. I have popupProperties which is just default stuff. I then call to the service which returns specific overrides depending on the popup. How can I iterate through all of the service's overrides and apply them to the popupProperties?
var popupProperties = getDefaultPopupProperties();
var popupOverrides= popupService.getPopupOverrides(currPopupId);
angular.forEach(popupOverrides, function(popupProperty, propertyName){
//replace defaults with popupData's properties
});
You should have a look at the solution of Josh David Miller which uses the extend method of angular (documentation).
var defaults = {name:'John',age:17,weight:55};
var overrides = {name:'Jack',age:28,color:'brown'};
var props = angular.extend(defaults, overrides);
// result
props: {
name:'Jack',
age:28,
weight:55,
color:'brown'
}
The values are copied in the defaults variable. There is no need of using the return value (var props =).
I presume you mean both functions are returning objects with a number of properties (as opposed to an array).
If so, the following should work - just JavaScript, nothing AngularJS specific:
for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }
See this question for more details How can I merge properties of two JavaScript objects dynamically?

Angularjs autoselect dropdowns from model

I'm trying display some data loaded from a datastore and it's not reflecting changes on the UI. I created an example to show a general idea of what I'm trying to achieve.
http://plnkr.co/edit/MBHo88
Here is the link to angularjs example where they show when on click then dropdowns are clear out. If you replace the expression with one of the colors of the list dropdowns are well selected. Does this type of selection only work on user events?
http://docs.angularjs.org/api/ng.directive:select
Help is appreciated!!!
Actually the problem is that ngSelect compares objects using simple comparition operator ('=='), so two objects with same fields and values are considered as different objects.
So you better use strings and numbers as values ('select' parameter in expression of ngSelect directive).
Here is kind of solution for your plunker.
Aslo there are some discussion about this topic on GitHub:
https://github.com/angular/angular.js/issues/1302
https://github.com/angular/angular.js/issues/1032
Also as I headred there is some work in progress about adding custom comparor/hashing for ngSelect to be able to use ngSelect more easier on objects.
One mistake in the initialization of your controller. You have to refer to the objects in your palette, since these are watched on the view:
$scope.selectedColors.push({col: $scope.palette[2]});
$scope.selectedColors.push({col: $scope.palette[1]});
Same with your result:
$scope.result = { color: $scope.obj.codes[2] };
Then you need to watch the result. In the below example, select 1 receives the value from the initiating select, the second receives the value below in the palette. I don't know if that's what you wanted, but you can easily change it:
$scope.$watch('result', function(value) {
if(value) {
var index = value.color.code -1;
$scope.selectedColors[0] = {col: $scope.palette[index] };
$scope.selectedColors[1] = {col: $scope.palette[Math.max(index-1, 0)] };
}
}, true);
See plunkr.
Ok, I think I figured this out but thanks to #ValentynShybanov and #asgoth.
According to angularjs example ngModel is initialized with one of the objects from the array utilized in the dropdown population. So having an array as:
$scope.locations = [{ state: 'FL', city: 'Tampa'}, {state: 'FL', city: 'Sarasota'} ....];
And the dropdown is defined as:
<select ng-options="l.state group by l.city for l in locations" ng-model="city" required></select>
Then $scope.city is initialized as:
$scope.city = $scope.locations[0];
So far so good, right?!!!.. But I have multiple locations therefore multiple dropdowns. Also users can add/remove more. Like creating a table dynamically. And also, I needed to load data from the datastore.
Although I was building and assigning a similar value (e.g: Values from data store --> State = FL, City = Tampa; Therefore --> { state : 'FL', city : 'Tampa' }), angularjs wasn't able to match the value. I tried diff ways, like just assigning { city : 'Tampa' } or 'Tampa' or and or and or...
So what I did.. and I know is sort of nasty but works so far.. is to write a lookup function to return the value from $scope.locations. Thus I have:
$scope.lookupLocation = function(state, city){
for(var k = 0; k < $scope.locations.length; k++){
if($scope.locations[k].state == state && $scope.locations[k].city == city)
return $scope.locations[k];
}
return $scope.locations[0]; //-- default value if none matched
}
so, when I load the data from the datastore (data in json format) I call the lookupLocation function like:
$scope.city = $scope.lookupLocation(results[indexFromSomeLoop].location.state, results[indexFromSomeLoop].location.city);
And that preselects my values when loading data. This is what worked for me.
Thanks

Resources