contactManager.controller('contactsList',
function contactsList($scope){
$scope.myId = 0;
$scope.contacts = [{id:$scope.myId,name:'Default',mail:'test#cognizant.com',mobile:'000000'},
{id:$scope.myId++,name:'andefined',mail:'undefined#cognizant.com',mobile:'1111'}];
});
contactManager.controller('addContactCtrl',
function addContactCtrl($scope,$location){
$scope.contact = {};
$scope.add = function(){
if($scope.contact.name){
$scope.contact.id = $scope.myId++; // **Increment Doesn't happen Here. It assigns the same value evertime**
$scope.contacts.push($scope.contact);
$location.url('/');
}
else{
alert('Name is mandatory');
}
};
});
Increment doesn't happen in $scope.myId++ !
I'm trying the assign id's to every new contact added to the list, but the id's are not getting incremented !!
You are better off using a service that provides the ID for you. You can create a service as follows:
contactManager.service('uniqueIds', function () {
var currentId = null;
return {
getNextId: function () {
if (currentId === null) {
currentId = 0;
} else {
currentId = currentId + 1;
}
return currentId;
}
}:
});
You can then use this service in your controllers as follows:
contactManager.controller('contactsList', ['$scope', 'uniqueIds', function ($scope, uniqueIds) {
$scope.contacts = {
id: uniqueIds.getNextId(), //Service call
name: 'Default',
mail: 'test#abc.com',
mobile:'000000'
}, {
id: uniqueIds.getNextId(), //Service call
name: 'undefined',
mail: 'undefined#xyz.com',
mobile:'1111'
}];
});
contactManager.controller('addContactCtrl', ['$scope', '$location', 'uniqueIds', function ($scope, $location, uniqueIds) {
$scope.contact = {};
$scope.add = function(){
if($scope.contact.name){
$scope.contact.id = uniqueIds.getNextId(); //Service call
$scope.contacts.push($scope.contact);
$location.url('/');
} else {
alert('Name is mandatory');
}
};
});
EDIT: If you are looking to generate uniqueIds, then this is not the way to go - You may want to check this out to generate them.
Related
I want to pass value from ng-click inside button, to athor html page (controller).
I have one page with 'getPersonalCtrl' controller that get my vaue from ng-click,
and want to sent this value to athor controller 'viewPersonalCtrl' in a diffrent html page, but I cant get the value.
this is my getPersonalCtrl (controller):
mymedical.controller('getPersonalCtrl',['$scope','$http','$cookies','myService',function($scope,$http,$cookies,myService) {
$scope.viewCurrent = function(value){
$scope.information = value;
myService.setInfo($scope.information);
///window.location="viewDetails.html";
}
}]);
this is my viewPersonalCtrl (controller) that I want to send the data to:
mymedical.controller('viewPersonalCtrl',['$scope','$http','$cookies','myService', function($scope,$http,$cookies,myService){
$scope.myreturnedData = myService.getInfo();
console.log($scope.myreturnedData);
}]);
mymedical.factory('myService', function(){
console.log("factory");
var infoObj = null;//the object to hold our data
return {
getInfo:function(){
console.log("getInfo");
console.log(infoObj);
return infoObj;
},
setInfo:function(value){
//console.log("setInfo");
//console.log(value);
infoObj = value;
}
}
});
what I need to do to fix it?
Thanks,
Can you please try like the below code?
mymedical.factory('dummyFactory', [function () {
var infoObj = null;
var myServiceFactory = {
setObj: function (value) {
infoObj = value;
},
getObj: function () {
return infoObj;
}
};
return myServiceFactory;
}]);
in controller:
dummyFactory.setObj(null);
var val2 = dummyFactory.getObj();
val2 will be null in console.
I'm sending a data ...
....
// upload on file select or drop
$scope.upload = function (file, id) {
id = typeof id !== 'undefined' ? id : null;
Upload.base64DataUrl(file).then(function(base64){
//auth
var fbAuth = FirebaseURL.getAuth();
//Ref
var ref = FirebaseURL.child("users_photos");
ref.push({'image': base64,'removed': true, 'user_id': fbAuth.uid, 'dt_created':Firebase.ServerValue.TIMESTAMP ,'dt_updated':Firebase.ServerValue.TIMESTAMP}, function(error){
if (error) {
alert('Error');
} else {
var newID = ref.key();
//I would like display data insert here?
console.log(DATA RESULT INSERT);
}
});
});
I would like display data inserted.
It is possible to display the last inserted object without query by the key?
Use AngularFire for synchronized collections.
Create a query using limitToLast(1) to always sync the last inserted object.
angular.module('app', ['firebase'])
.constant('FirebaseUrl', '<my-firebase-app>')
.service('rootRef', ['FirebaseUrl', Firebase)
.factory('userItems', UserItems)
.controller('MyCtrl', MyController);
function UserItems($firebaseArray, rootRef) {
return function userItems(uid) {
var itemRef = rootRef.child('items');
var query = itemRef.orderyByChild('uid').equalTo(uid);
return $firebaseArray(query);
}
}
function MyController($scope, userItems, rootRef) {
$scope.items = userItems(rootRef.getAuth().uid);
$scope.addItem = function addItem(item) {
$scope.items.$add(item).then(function(ref) {
var record = $scope.items.$getRecord(ref.key());
// save the data to the other structure
});
};
}
See the section on Complex queries for more info.
I need to use $q to wait until my async function has completed and then do something.
However I have tried injecting $q into my angular module as well as my angular functions and I am getting the message $q is undefined.
Can someone tell me how I can go about being able to use this in my code?
Here is the code for the module and the function I want to use $q in respectively
Module
var droidSync = angular.module('droidSync', ['ionic', 'ngRoute', 'ui.router']);
Controller and FunctionIn this case I want to wait for the results.forEach to finish then I want to hide my loading screen using $ionicLoading.hide()
droidSync.controller('mainController', function ($scope, $ionicLoading) {
$scope.syncContacts = function () {
//Display a loading screen while sync is in execution
$ionicLoading.show({
template: '<p>Syncing Contacts...</p><ion-spinner class="spinner-calm" icon="crescent"/>'
});
var table = AzureService.getTable('contact');
table.read().done(function (results) {
results.forEach(function (result) { //THIS NEEDS TO BE COMPLETE BEFORE HIDING LOAD SCREEN
console.log('result is', result);
// If the contact is flagged as deleted check if its on the device and delete it
if (result.isdeleted == true) {
var options = new ContactFindOptions();
options.filter = result.id;
options.multiple = false;
var fields = ["*"];
navigator.contacts.find(fields, findSuccess, findError, options);
function findSuccess(contact) {
if (contact.length > 0) {
console.log("inside the delete area:", contact);
var contactToDelete = navigator.contacts.create();
//It is safe to use contact[0] as there will only ever be one returned as AzureID is unique
contactToDelete.id = contact[0].id;
contactToDelete.rawId = contact[0].id;
console.log('we want to delete this', contactToDelete);
contactToDelete.remove();
console.log('Contact Deleted');
}
else {
console.log('Contact to delete not present on device. Checking next contact');
}
}
function findError() {
console.log('Contact search failed: Deleted Contact Search');
}
}
else {
//create a contact object to save or update
var emails = [];
var phoneNumbers = [];
var name = new ContactName();
var contactToUpdate = navigator.contacts.create();
contactToUpdate.note = result.id;
name.givenName = result.firstname;
name.familyName = result.lastname;
phoneNumbers[0] = new ContactField('mobile', result.mobilephone, true);
phoneNumbers[1] = new ContactField('home', result.homephone, false);
emails[0] = new ContactField('work', result.email, true);
contactToUpdate.name = name;
contactToUpdate.phoneNumbers = phoneNumbers;
contactToUpdate.emails = emails;
//Search for the contact on the device
var options = new ContactFindOptions();
options.filter = result.id;
options.multiple = false;
var fields = ["*"];
navigator.contacts.find(fields, foundSuccess, foundError, options);
function foundSuccess(contact) {
if (contact.length > 0) {
//The contact has been found on the device. Pass in ids for contact, emails and phone numbers to update.
console.log('object to update is object is', contact);
console.log('contact array length is ', contact.length);
contactToUpdate.id = contact[0].id;
contactToUpdate.rawId = contact[0].rawId;
contactToUpdate.phoneNumbers[0].id = contact[0].phoneNumbers[0].id;
contactToUpdate.phoneNumbers[1].id = contact[0].phoneNumbers[1].id;
contactToUpdate.emails[0].id = contact[0].emails[0].id;
console.log('about to save this', contactToUpdate);
contactToUpdate.save(upSuccess, upError);
function upSuccess() {
console.log('updated a contact!');
}
function upError(ContactError) {
console.log('error updating a contact!');
}
}
else {
//The contact does not exist on the device. Just save it.
console.log('non existent contact: ', contactToUpdate);
contactToUpdate.save(saveSuccess, SaveError);
function saveSuccess() {
console.log('saved a contact!');
}
function SaveError() {
console.log('error saving a contact!');
}
}
}
function foundError() {
console.log('Contact search failed: Undeleted Contact Search');
}
} // end else
})) // end forEach
}) // table.read()
}; // scope.syncContacts()
});
So i'd probably do something like this
This is completely untested code so take that for what you will
$q.all is what your going to want to look into
droidSync.controller('mainController', ["$scope", "$q", "$ionicLoading",
function ($scope, $q, $ionicLoading) {
var loop = function(result){
var deferred = $q.defer();
deferred.resolve(// your loop stuff);
return deferred.promise;
};
var loopingFunction = function(results){
var promises = [];
results.forEach(function(result){
promises.push(loop(result));
});
return $q.all(promises);
};
$scope.syncContacts = function () {
//Display a loading screen while sync is in execution
$ionicLoading.show({
template: '<p>Syncing Contacts...</p><ion-spinner class="spinner-calm" icon="crescent"/>'
});
var table = AzureService.getTable('contact');
table.read().done(function (results) {
loopingFunction(results).then(function(){
// do something after it finishes
$ionicLoading.hide()
});
});
};
}]);
I am using angularJS. Right now I have a function that creates a "new project" (an object) which sends it to the server.
The sidebar is populated with a list of projects that it gets from the server. Each time the page is reloaded is calls a function "loadProjects" and it generates the list.
To make a new project appear on the sidebar without having to refresh the page I made a timeout function because if I call both the "postProject" and "loadProjects" it would not work.
function RefreshSidebar() {
setTimeout(loadProjects, 200);
}
This code works but I want to make it doesn't feel right. I want to make it right and I think I should be using a promise call for this. The problem that I am facing is that the first function being called (addProject) is inside a Controller for the "Add new Project" custom directive and the second one is inside the mainController.
This is my app.directive.js:
(function() {
angular
.module("app.directive", [])
.directive("createProject", CreateProjDirective)
.directive("viewProject", ViewProjDirective);
function ViewProjDirective() {
return {
restrict: "EA",
templateUrl: "directives/project_view.html"
};
}
function CreateProjDirective() {
return {
restrict: "EA",
controller: CreateController,
controllerAs: "proj",
templateUrl: "directives/create_project.html"
};
}
function CreateController($scope, $http, $timeout) {
var proj = this;
var counter = 001;
proj.id = "ProjectTest_"+counter
proj.uuid = "";
proj.customer = "";
proj.socket = "";
proj.drawing = "";
proj.programmer = "";
proj.createdOn = new Date();
proj.revision = "";
proj.protocol = "";
proj.targetMachineId = "";
$scope.posttest = "";
proj.addProject = function(){
var dataProj = {
"Description": {
ProjectID: proj.id,
UUID: proj.uuid,
Customer: proj.customer,
Socket: proj.socket,
Drawing: proj.drawing,
Programmer: proj.programmer,
CreatedOn: proj.createdOn,
Revision: proj.revision,
ProtocolFileSchema: proj.protocol,
TargetMachineID: proj.targetMachineId
}
};
var request = $http.post('http://localhost:9001/api/projects/', dataProj) ;
request.success(function(data, status, headers, config) {
console.log(data);
$scope.message = data;
});
request.error(function(data, status, headers, config) {
alert( "failure message: " + JSON.stringify({data: data}));
});
//reset the form
counter = counter + 1;
proj.id = "ProjectTest_"+counter;
proj.uuid = "";
proj.customer = "";
proj.socket = "";
proj.drawing = "";
proj.programmer = "";
proj.createdOn = new Date();
proj.revision = "";
proj.protocol = "";
proj.targetMachineId = "";
$scope.posttest = "";
}
};
})();
And this is my app.controller.js (I think the only relevant functions here is loadProjects() and refreshSidebar()
(function() {
angular
.module("app.controller", [])
.controller('AppCtrl', MainController);
MainController.$inject = ['$scope', '$mdSidenav', 'ilcamService', '$timeout','$log', "$http"];
function MainController($scope, $mdSidenav, ilcamService, $timeout, $log, $http) {
var allProjects = [];
//com directive-controller $scope.$on("testEvent", function(event, data) { $scope.test = data; console.log(data); });
$scope.create = false;
$scope.selected = null;
$scope.projects = allProjects;
$scope.selectProject = selectProject;
$scope.toggleSidenav = toggleSidenav;
$scope.refreshSidebar = refreshSidebar;
$scope.putProject = putProject;
loadProjects();
function loadProjects() {
ilcamService.loadAll()
.then(function(projects){
allProjects = projects;
console.log(projects);
$scope.projects = [].concat(projects);
$scope.selected = $scope.projects[0];
})
}
function toggleSidenav(name) {
$mdSidenav(name).toggle();
}
function selectProject(project) {
$scope.selected = angular.isNumber(project) ? $scope.projects[project] : project;
$scope.toggleSidenav('left');
$scope.create = 0;
}
function refreshSidebar() {
setTimeout(loadProjects, 200);
}
})();
My first idea was to inject the "app.directive" inside the "app.controller" so I could use addProject inside the controller, just like I injected "IlcamService" to use the "loadAll" but angular don't seem to allow me to inject a directive inside a controller. That makes sense because I actually want the controller that is inside that directive, not the entire directive but I dont know how to do that without moving the controller outside the directive file.
Create a service that will be responsible to make the requests, this service will have a method that returns a promise. Inside your controller inject the service and call the method that make the requests, when the promise resolves call then loadProjects method. Something like:
Service
app.service('LoadProjectsService', function($http){
_postProjects = function(){
return $http.post(...)
}
return{
postProjects: _postProjects
}
});
Controller
app.controller('YourController', ['LoadProjectsService', function(LoadProjectsService) {
LoadProjectsService.postProjects()
.success(
loadProjects()
)
}]);
Directive
app.directive('LoadProjectsService', function(LoadProjectsService) {
return {
template: ...
link: function(){
LoadProjectsService.postProjects()
.success(
loadProjects()
)
}
};
});
My problem consist in that I have some data in REST service and I want to get them and then send to rest of controllers. But I don't know how to do correctly because service $http.get() is perform asynchronously. I will show you piece of my code in order to better represent problem.
I created controller which is responslible for get data from REST service.
MyApp.controller("AppController", ["$scope", "$http", function($scope,$http) {
$http.get("http://localhost:8080/library/book").success(function(data) {
$scope.bookList = data;
});
$http.get("http://localhost:8080/library/author").success(function(data) {
$scope.authorList = data;
});
$http.get("http://localhost:8080/library/publisher").success(function(data) {
$scope.publisherList = data;
});
}]);
BookList, authorList, publisherList are building materials for rest of controllers.
Ok, I show other piece of code.
MyApp.service("BookListModel", function() {
this.createBookList = function(bookList, authorList, publisherList) {
var i = 0, j = 0, authorName, publisherName, bookListItems = [];
for(; i < bookList.length; i++) {
for(; j < authorList.length; j++) {
if(bookList[i].authorId == authorList[j].authorId) {
authorName = authorList[j].name;
}
}
j = 0;
for(; j < publisherList.length; j++) {
if(bookList[i].publisherId == publisherList[j].publisherId) {
publisherName = publisherList[j].name;
}
}
j = 0;
bookListItems.push({'title' : bookList[i].title, 'author' : authorName, 'publisher' : publisherName});
authorName = "", publisherName = "";
}
return bookListItems;
};
});
For example this is one of my serivces. It create book list with authors and publishers and it take three arguments and I don't know how pass data from AppController to createBookList function.
Use a factory/service to make your REST calls (don't do it in a controller).
If you're making all these calls at the same time, you can use $q.all() to combine the promises and get a single promise.
Whenever a controller gets that promise, they'll get the same data each time and your REST services will only be called once.
Your controllers just call LibraryService.getLibraryData() and handle the promise to get the data itself.
MyApp.factory('LibraryService', function($http, $q){
var service = {};
var libraryDataPromise = $q.defer();
$q.all({
books: $http.get("http://localhost:8080/library/book"),
authors: $http.get("http://localhost:8080/library/author"),
publishers: $http.get("http://localhost:8080/library/publisher"),
}).then(function(response){
libraryDataPromise.resolve({
bookList: response.books,
authorList: response.authors,
publisherList: response.publishers
});
});
service.getLibraryData = function() {
return libraryDataPromise.promise;
};
return service;
});
You can also do an angular broadcast. In your 'AppController':
....
http.get("http://localhost:8080/library/book").success(function(data) {
$scope.$broadcast('bookList-updated', data);
}
....
Then in your other controllers where you want to use the data do this:
....
$scope.$on('booklist-updated', function(event, booklist){
$scope.booklist = booklist;
});
....
Use angular services
app.service('mySharedService', function ($rootScope) {
this.bookList = [];
this.authorList = [];
this.publisherList = [];
this.setBookList = function (bookList) {
this.bookList = bookList;
};
this.setPublisherList = function (publisherList ) {
this.publisherList = publisherList ;
};
this.setAuthorList = function (authorList ) {
this.authorList = authorList ;
};
this.getBookList = function () {
return this.bookList;
};
this.getPublisherList = function () {
return this.publisherList;
};
this.getAuthorList = function () {
return this.authorList;
};
});
Make sure to pass\inject your service to your controller
MyApp.controller("AppController", ["$scope", "$http", "mySharedService", function($scope,$http) {
$http.get("http://localhost:8080/library/book").success(function(data) {
$scope.bookList = data;
mySharedService.setBookList(data);
});
$http.get("http://localhost:8080/library/author").success(function(data) {
$scope.authorList = data;
mySharedService.setPublisherList(data);
});
$http.get("http://localhost:8080/library/publisher").success(function(data) {
$scope.publisherList = data;
mySharedService.setAuthorList(data);
});
}]);
NOTE: I didn't test the code.