that's how i did it, i will teach how from start to finish
starting from the Node.js part, I use Sails.js and lodash
SetSportsController.js
'use strict'; module.exports = { setCheck: function(req, res) { var checkedSportParams = req.body; SportSelectionService.sportChecked(checkedSportParams).then(function() { res.json(200, {msg: 'OK'}); }, function(err) { res.json(400, err); }); }, retrieveSetCheck: function(req, res) { if (req.params) { SportSelectionService.getSportChecked(req.params).then(function(sportChecked) { res.json(200, sportChecked); }, function(err) { res.json(400, err); }); }else { res.json(400, {error: 'Error retrieving Sports'}); } } };
than SportSelectionService.js
'use strict'; var _ = require('lodash'); module.exports = { sportChecked: function(params) { var Promise = require('bluebird'); return new Promise(function(fullfill, reject) { SportSelection.findOne({ user: params.user }).exec(function(err, sportChecked) {//this array comes with duplicates var newSport, sportCheckedUniq = _.uniq(sportChecked.sport);//prevents duplicates if (err) { reject(new Error('Error finding user')); console.error(err); }else if (sportChecked) { newSport = sportCheckedUniq || []; if (_.includes(sportCheckedUniq, params.sport)) { sportCheckedUniq = _.pull(newSport, params.sport); sportCheckedUniq = _.difference(newSport, params.sport); }else { newSport.push(params.sport); sportCheckedUniq = newSport; } SportSelection.update({ user: params.user }, { sport: newSport }).exec(function(err, sportCheckedUpdated) { if (err) { reject(new Error('Error on sportChecked')); }else { fullfill(sportCheckedUpdated); } }); if (sportCheckedUniq) { sportCheckedUniq.push(params.sport); }else { sportCheckedUniq = [params.sport]; } }else { SportSelection.create({ sport: [params.sport], user: params.user }).exec(function(err, created) { if (err) { reject(new Error('Error on sportChecked')); }else { fullfill(created); } }); } }); }); }, getSportChecked: function(params) { var Promise = require('bluebird'); return new Promise(function(fullfill, reject) { console.time('sportChecked_findOne'); SportSelection.findOne({ user: params.user }).exec(function(err, sportChecked) { console.timeEnd('sportChecked_findOne'); if (err) { reject(new Error('Error finding sportChecked')); console.error(err); }else { if (sportChecked) { fullfill(sportChecked); }else { SportSelection.create({ // 10 is the ID for soccer, which must unchecked by default on every single user. sport: [10], user: params.user }).exec(function(err, created) { console.log(err); console.log(created); if (err) { reject(new Error('Error on sportChecked')); }else { fullfill(created); } }); } } }); }); } };
as you can see here, we have only 2 methods, the first
sportChecked() is the one that fires when the user checks or deselects any of the elements.
and then we have getSportChecked() , which is a method called every time the user logs in again.
I don’t have a deletion method, because we don’t delete anything, we just watch the instruction change.
I also work with a Redis server
Remember to create a model, I gave'em the name SportSelection.js
'use strict'; module.exports = { connection: 'RedisServer', attributes: { sport: { type: 'array', required: false }, user: { type: 'string', required: true } } };
In addition, there is policy.js in the config folder, I can not tell you how to work with this, because this is your configuration, but mine:
SetSportsController: { setCheck: ['jwtAuth', 'sanitizerPolicy', 'headersPolicy'], retrieveSetCheck: ['jwtAuth', 'sanitizerPolicy'] },...
then go to the Front End Part (remember: AngularJS)
I have a controller, controller.js
$scope.toggleSportSelection = function(sport) { SportsFactory.setSportChecked({ user: $scope.customer.customer, sport: sport.id }).then(function() { sport.checked = !sport.checked; $ionicScrollDelegate.resize(); }, function() { $ionicScrollDelegate.resize(); }); };
which works according to this template
<ion-item ng-repeat="sport in sportsFilter track by $index" ng-click="toggleSportSelection(sport)"> {{:: sport.name}} </ion-item>
then service.js
know AngularJS
that's where i make a message and get watch
.factory('SportsFactory', function($http, $q, AuthFactory, LocalForageFactory, LeaguesFactory, ImageFactory, CONSTANT_VARS) { getSports: function(customer) { var defer = $q.defer(), _this = this; LocalForageFactory.retrieve(CONSTANT_VARS.LOCALFORAGE_SPORTS) .then(function(sports) { if (!_.isNull(sports)) { defer.resolve(sports); }else { $http.get(CONSTANT_VARS.BACKEND_URL + '/lines/sports/' + customer.agent) .success(function(sports) { sports = _.sortBy(sports, function(sport) { return sport.priority; }); _this.getSportChecked(customer).then(function(sportChecked) { var sportIds = _.pluck(sports, 'id'), intersectedSports = _.intersection(sportIds, sportChecked.sport); if (sports.length) { sports = _.map(sports, function(sport) { sport.checked = !_.includes(intersectedSports, sport.id); return sport; }); }else { AuthFactory.logout(); } }); _.each(sports, function(sport) { var sportImg = ImageFactory.sportImages(sport); if (sportImg.length) { sport.img = sportImg[0]; }else { sport.img = 'https://placehold.it/40x40'; } }); defer.resolve(sports); }) .error(function(err) { defer.reject(err); }); } }); return defer.promise; }, setSportChecked: function(params) { var defer = $q.defer(); $http.post(CONSTANT_VARS.BACKEND_URL + '/sports/checked', params) .success(function(sportChecked) { LocalForageFactory.remove(CONSTANT_VARS.LOCALFORAGE_SPORTS_CHECKED, params); defer.resolve(sportChecked); }) .error(function(err) { console.log(err); defer.reject(err); }); return defer.promise; }, getSportChecked: function(customer) { var defer = $q.defer(), user, rejection = function(err) { defer.reject(err); }; LocalForageFactory.retrieve(CONSTANT_VARS.LOCALFORAGE_SPORTS_CHECKED) .then(function(sportChecked) { user = customer.customer; if (!_.isNull(sportChecked)) { defer.resolve(sportChecked); }else { $http.get(CONSTANT_VARS.BACKEND_URL + '/sports/getChecked/' + user) .success(function(sportChecked) { LocalForageFactory.set(CONSTANT_VARS.LOCALFORAGE_SPORTS_CHECKED, sportChecked); defer.resolve(sportChecked); }) .error(rejection); } }, rejection); return defer.promise; } });
first focus on setSportChecked() and getSportChecked() , where the magic happens in this service, then the getSports() function calls getSportChecked() , which looks like this
_this.getSportChecked(customer).then(function(sportChecked) { var sportIds = _.pluck(sports, 'id'), intersectedSports = _.intersection(sportIds, sportChecked.sport); if (sports.length) { sports = _.map(sports, function(sport) { sport.checked = !_.includes(intersectedSports, sport.id); return sport; }); }else { AuthFactory.logout(); } });
So, this is the final version, if this is a long project, you need to touch a large number of files to get with it, save / transfer data to the database, so see this code, because I still work fine with it and quickly, I don’t have any errors so far, looking up from here, ask the questions you need to know, I will answer during the day. Hope this helps