I have a simple app that shows a list of people each with a link to an edit controller. The edit controller gets the person by id. Once the edit form has been submitted, the page is redirected back to the person list.
I have a method to update the service data in the callback after the server saves the person. The method I use does in fact work, however, I wasn't sure if there was a better way to achieve this. After much searching I haven't found a concrete answer so I wanted to reach out to the AngularJS community here for help.
Here is a fiddle: http://jsfiddle.net/7bGEG/
var app = angular.module('peopleApp',[]);
app.controller('ListCtrl',function($scope,People) {
People.getList().then(function(response) {
$scope.list = response; // show list of people with a link to new route to edit
});
});
app.controller('EditCtrl',function($scope,$location,$routeParams,People) {
// edit route so get person by id
People.getById($routeParams.id).then(function(response) {
$scope.person = response.person;
});
// submit save person form and send back to person list
$scope.savePerson = function() {
People.savePerson($scope.person).then(function(response) {
$location.path('/');
});
}
});
app.factory('People',function($http,$q) {
var people = [];
var people_q = $q.defer();
$http.get(url).then(function(response) {
people = response.data;
people_q.resolve(people);
});
return {
getList: function() {
return people_q.promise;
},
getById: function(id) {
return $http.get(url).then(function(response) {
return response.data;
});
},
savePerson: function(person) {
return $http.post(url).then(function(response) {
// find person in person array and remove them
for (i=0; i < people.length; i++) {
if (people[i].person_id == person.person_id) {
people.splice(i,1);
break;
}
}
// add new person data
people.push(response.data);
return response.data;
});
}
}
});
Related
I need a bit of guidance figuring out how to make two similar values in angular js from two different tables. The tables am using are a user table and a school table. So what I need to do is based on the logged in user I am supposed to get a school name related to that user but currently am not sure how to go about this. Any assistance in guiding me on how to go about this would be greatly appreciated.
School Service Controller Code:
angular.module('starter').factory('Schools',['apiUrl','$resource', 'UserInfo', function(apiUrl,$resource, UserInfo){
var factory = $resource(apiUrl + '/schools/:schoolId',
{
schoolId: '#_id'
}, {
update: {
method: 'GET'
}
});
return factory;
}]);
Profile Controller Code Snippet:
angular.module('starter.controllers')
.controller('ProfileController', function($scope,$http,$state,Schools, $ionicPopup, apiUrl, UserInfo,$ionicLoading,$ionicHistory,Users,Authentication) {
$scope.apiUrl = apiUrl;
$scope.authentication = Authentication;
$scope.state = $state;
$scope.selected = {};
var user = Authentication.user.school;
$scope.find = function(queryParams){
$scope.place = [];
var user = $scope.authentication.user.school;
var school = Schools.query({_id: user.school})
var params = queryParams || {};
params._id = user;
Schools.query(params, function(response){
if (params._id === school){
// response.splice(0, $scope.place.lengh);
// for(var x = 0; x< response.lengh; x++){
// $scope.place.push(response[x]);
// }
$scope.place = response[0].name;
}
else{
$scope.place = response;
}
})
}
$scope.signOut = function(){
$ionicPopup.confirm({
title: "SIGN OUT",
template: '<p align="center">' + 'PLEASE CONFIRM IF YOU WANT TO SIGN OUT'+ '</p>',
buttons: [
{ text: "NO",
type: 'button button-outline button-assertive',
onTap:function(e){
return false;
}
},
{
text: "YES",
type:'button-positive',
onTap:function(e){
//now you can clear history or goto another state if you need
$ionicHistory.clearHistory();
$ionicHistory.nextViewOptions({ disableBack: true, historyRoot: true });
$state.go('signin');
return true;
}
}
]
});
};
});
My value for "$scope.find function" is returned properly but is the whole list of school names and details rather than the one which matches the user.
I think this is server side logic. When you pass logged in user to your api then do some database query based on that user in the server side and return json object with all the list of schools .
I finally figured a way to get the correct values based on the id reference of school in the user table. I had to use the angularjs forEach method to first query the data then filter it in a if statement to get the results I was looking for.
Solution:
$scope.find = function(){
var school = $scope.authentication.user.school;
$scope.schoolName = Schools.query(function(results) {
results.forEach(function(result) {
if (result._id === school) {
$scope.schoolName = result.name;
return $scope.schoolName;
}
});
});
}
I'm using ionic v1 and trying to create list and its own detail, but when I click on the item list the detail view doesn't display the data of the item selected.
Factory
.factory('Eventos', function($http){
var eventos = [];
return {
all : function() {
return $http.get("eventos.json").then(function(response) {
eventos = response;
return eventos;
});
},
get : function(eventoId) {
for(i = 0; i < eventos.length; i++) {
if(eventos[i].id === eventoId){
return eventos[i];
}
}
return null;
}
}});
Controller
.controller('EventosCtrl', function($scope, $stateParams, Eventos) {
Eventos.all().then(function(eventos) {
$scope.eventos = eventos.data;
});
})
.controller('EventoCtrl', function($scope, $stateParams, Eventos) {
$scope.evento = Eventos.get($stateParams.eventoId);
}
But if I use the data static in the code this works, but I don't know whats wrong here.
If you're not running a webserver of any kind and just testing with file://index.html, then you're probably running into same-origin policy issues.
Many browsers don't allow locally hosted files to access other locally hosted files.
Try referencing your data as an object
var obj = {list:null};
$http.get('data.json').success(function(data) {
// you can do some processing here
obj.list = data;
});
return obj;
I am trying to perform a get request, in the post request everything is OK, I can see that in the post request all I do it's been save, once I refresh the page I am printing in the console the items saved by the post request, but those items aren't been return with the get I am doing.
here is where everything begins, I have a list of items here with the option to checked or unchecked the items in the list
<ion-item ng-repeat="sport in sports" ng-click="toggleSportSelection(sport)">
{{:: sport.name}}
</ion-item>
all the items are checked = true by default, so what I am saving, are the items with checked = false, the items checked = true you can see them here
<div ng-show="sport.checked" ng-repeat="sport in sports">
{{sport.name}}
</div>
this is what I have in the controller
.controller('SportsController', function($scope, SportsFactory) {
SportsFactory.getSportChecked(customer).then(function(sportChecked) {
_.each(sports, function(sport) {
var sportIds = _.pluck(sport, 'id'),
intersectedSports = _.intersection(sport.id, sportChecked),
checkedSportObjects = _.filter(sport, function(sportObj) {
return _.includes(intersectedSports, sportObj);
});
_.each(checkedSportObjects, function(sport) {
$scope.sports.push(sport);
});
});
}, function(err) {
console.log(err);
});
$scope.toggleSportSelection = function(sport) {
var params = {};
params.user = $scope.customer.customer;
params.sport = sport.id;
sport.checked = !sport.checked;
SportsFactory.setSportChecked(params);
};
// this is what puts the sports on checked = true
if (sports.length) {
$scope.sports = _.map(sports, function(sport) {
sport.checked = true;
return sport;
});
}
and this is the service / factory
.factory('SportsFactory', function($http, $q, AuthFactory,
LocalForageFactory, CONSTANT_VARS) {
return {
getSportChecked: function(customer) {
var defer = $q.defer(),
user,
rejection = function(err) {
console.log(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;
}
});
I am working along with NodeJS, so if you want the code I have in that part just let me know, so far I think that the issue I have is in the front end part, in the controller.
I'm trying to get all the contacts in the phone using ng-cordova, I success to do that like the following, I create a service in AngularJS:
.factory("ContactManager", function($cordovaContacts) {
return {
getContacts: function() {
var options = {};
options.filter = "";
options.multiple = true;
//get the phone contacts
return $cordovaContacts.find(options);
}
}
})
Also the method find in the ng-cordova is't like the following:
find: function (options) {
var q = $q.defer();
var fields = options.fields || ['id', 'displayName'];
delete options.fields;
navigator.contacts.find(fields, function (results) {
q.resolve(results);
},
function (err) {
q.reject(err);
},
options);
return q.promise;
}
And did the following inside the controller:
ContactManager.getContacts().then(function(result){
$scope.users= result;
}, function(error){
console.log(error);
});
I noticed that in the $scope.users I find the formatted, middleName ..., but I can't find the phoneNumber, how can I get also the phoneNumbers?
If you log the contacts you should see an object with a phoneNumbers array in it.
ContactManager.getContacts().then(function(result){
$scope.users= result;
console.log(result);
...
If you don't it's something else.
I also made a somewhat close mock json of what the return looks like.
I have this service:
factory('Post', function($resource) {
return $resource('/api/post.json', {},
{
query: {method:'GET', isArray: false}
}
);
})
And I have this controller:
function PostsCtrl($scope, Post) {
// init
$scope.page = 0;
$scope.page_has_next = true;
$scope.loadMore = function() {
if($scope.page_has_next) {
$scope.posts = Post.query({page: ++$scope.page},
function(data) {
$scope.page_has_next = data.has_next;
}
);
}
}
$scope.loadMore();
}
This works just fine, each time loadMore() is executed the model gets updated with the next page until there are no more pages. However, I want to append the new set of posts to the current model instead of replacing it, how can I do that?
Assuming that posts is a array:
$scope.posts = $scope.posts.concat(Post.query({page: ++$scope.page})
This will only work if the new posts has no duplicates with the old posts. If there are duplicates, you have to traverse the array and push only new posts.