AngularJS : From a factory, how can I call another function - function

Do I have to move my getTemplates function out of the return or what ?
Example : I dont know what to replace "XXXXXXX" with (I have tried "this/self/templateFactory" etc... ) :
.factory('templateFactory', [
'$http',
function($http) {
var templates = [];
return {
getTemplates : function () {
$http
.get('../api/index.php/path/templates.json')
.success ( function (data) {
templates = data;
});
return templates;
},
delete : function (id) {
$http.delete('../api/index.php/path/templates/' + id + '.json')
.success(function() {
templates = XXXXXXX.getTemplates();
});
}
};
}
])

By doing templates = this.getTemplates(); you are referring to an object property that is not yet instantiated.
Instead you can gradually populate the object:
.factory('templateFactory', ['$http', function($http) {
var templates = [];
var obj = {};
obj.getTemplates = function(){
$http.get('../api/index.php/path/templates.json')
.success ( function (data) {
templates = data;
});
return templates;
}
obj.delete = function (id) {
$http.delete('../api/index.php/path/templates/' + id + '.json')
.success(function() {
templates = obj.getTemplates();
});
}
return obj;
}]);

How about this?
.factory('templateFactory', [
'$http',
function($http) {
var templates = [];
var some_object = {
getTemplates: function() {
$http
.get('../api/index.php/path/templates.json')
.success(function(data) {
templates = data;
});
return templates;
},
delete: function(id) {
$http.delete('../api/index.php/path/templates/' + id + '.json')
.success(function() {
templates = some_object.getTemplates();
});
}
};
return some_object
}
])

Related

Routing is not working in AngularJS

The routing is not working for the index.html. It is even giving a compiler error. Index.html is my startup page. Through Header details link the Add Header.html page should open. I have added the whole code in plunkr ["https://plnkr.co/edit/w9eWiHKvSDrf0viERgoX?p=preview"]
app.js
var MyApp = angular.module('MyApp', ['ngRoute']);
// configure our routes
MyApp.config(function ($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl: 'AddHeader.html',
controller: 'headerCtrl'
})
.when('/AddHeader', {
templateUrl: 'AddHeader.html',
controller: 'headerCtrl'
})
// route for the about page
.when('/ProjectIDCreation', {
templateUrl: '/ProjectIDCreation.html',
controller: 'headerCtrl'
})
});
HeaderCtrl.js
var app = angular.module('MyApp');
var baseAddress = 'http://localhost:49754/api/TimeSheet/';
var url = "";
//var app = angular.module('MyApp');
//app.controller('mainController', function ($scope) {
// console.log('mainController');
//});
app.factory('userFactory', function ($http) {
return {
getHeadersList: function () {
url = baseAddress + "FetchHeaderDetails";
return $http.get(url);
},
addHeader: function (user) {
url = baseAddress + "InsertHeaderDetails";
return $http.post(url, user);
},
updateHeader: function (user) {
url = baseAddress + "UpdateHeaderDetails";
return $http.put(url, user);
}
};
});
//var app = angular.module('MyApp');
app.controller('headerCtrl', function PostController($scope, userFactory) {
$scope.users = [];
$scope.user = null;
$scope.editMode = false;
//Fetch all Headers
$scope.getAll = function () {
userFactory.getHeadersList().success(function (data) {
$scope.users = data;
}).error(function (data) {
$scope.error = "An Error has occured while Loading users! " + data.ExceptionMessage;
});
};
//Add Header
$scope.add = function () {
var currentUser = this.user;
userFactory.addHeader(currentUser).success(function (data) {
$scope.addMode = false;
currentUser.HeaderID = data;
$scope.users.push(currentUser);
$scope.user = null;
$('#userModel').modal('hide');
}).error(function (data) {
$scope.error = "An Error has occured while Adding user! " + data.ExceptionMessage;
});
};
//Edit Header
$scope.edit = function () {
$scope.user = this.user;
$scope.editMode = true;
$('#userModel').modal('show');
};
//Update Header
$scope.update = function () {
var currentUser = this.user;
userFactory.updateHeader(currentUser).success(function (data) {
currentUser.editMode = false;
$('#userModel').modal('hide');
}).error(function (data) {
$scope.error = "An Error has occured while Updating user! " + data.ExceptionMessage;
});
};
//Model popup events
$scope.showadd = function () {
$scope.user = null;
$scope.editMode = false;
$('#userModel').modal('show');
};
$scope.showedit = function () {
$('#userModel').modal('show');
};
$scope.cancel = function () {
$scope.user = null;
$('#userModel').modal('hide');
}
// initialize your users data
$scope.getAll();
});
Make sure the file path which you have used in script tags are correct. Which in the plnkr were not correct. Also i found you had two modules defined avoid doing that. Also you are importing angular, jquery, bootstrap more than once dont do that.
Below is the corrected code
Edited plnkr
var app = angular.module('MyApp', ['ngRoute']);
// configure our routes
app.config(function ($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl: 'AddHeader.html',
controller: 'headerCtrl'
})
.when('/AddHeader', {
templateUrl: 'AddHeader.html',
controller: 'headerCtrl'
})
// route for the about page
.when('/ProjectIDCreation', {
templateUrl: 'ProjectIDCreation.html',
controller: 'headerCtrl'
})
});
var baseAddress = 'http://localhost:49754/api/TimeSheet/';
var url = "";
app.factory('userFactory', function ($http) {
return {
getHeadersList: function () {
url = baseAddress + "FetchHeaderDetails";
return $http.get(url);
},
addHeader: function (user) {
url = baseAddress + "InsertHeaderDetails";
return $http.post(url, user);
},
updateHeader: function (user) {
url = baseAddress + "UpdateHeaderDetails";
return $http.put(url, user);
}
};
});
//var app = angular.module('MyApp');
app.controller('headerCtrl', function PostController($scope, userFactory) {
$scope.users = [];
$scope.user = null;
$scope.editMode = false;
//Fetch all Headers
$scope.getAll = function () {
userFactory.getHeadersList().success(function (data) {
$scope.users = data;
}).error(function (data) {
$scope.error = "An Error has occured while Loading users! " + data.ExceptionMessage;
});
};
//Add Header
$scope.add = function () {
var currentUser = this.user;
userFactory.addHeader(currentUser).success(function (data) {
$scope.addMode = false;
currentUser.HeaderID = data;
$scope.users.push(currentUser);
$scope.user = null;
$('#userModel').modal('hide');
}).error(function (data) {
$scope.error = "An Error has occured while Adding user! " + data.ExceptionMessage;
});
};
//Edit Header
$scope.edit = function () {
$scope.user = this.user;
$scope.editMode = true;
$('#userModel').modal('show');
};
//Update Header
$scope.update = function () {
var currentUser = this.user;
userFactory.updateHeader(currentUser).success(function (data) {
currentUser.editMode = false;
$('#userModel').modal('hide');
}).error(function (data) {
$scope.error = "An Error has occured while Updating user! " + data.ExceptionMessage;
});
};
//Model popup events
$scope.showadd = function () {
$scope.user = null;
$scope.editMode = false;
$('#userModel').modal('show');
};
$scope.showedit = function () {
$('#userModel').modal('show');
};
$scope.cancel = function () {
$scope.user = null;
$('#userModel').modal('hide');
}
// initialize your users data
$scope.getAll();
});
<li></i>AddHeader</li>
<li></i>ProjectIDCreation</li>
(in .html don't forget / )
.config(
[ '$locationProvider', '$routeProvider',
function config($locationProvider, $routeProvider) {
$locationProvider.hashPrefix('!');
.when('/AddHeader', {
templateUrl: 'AddHeader.html',
controller: 'headerCtrl'
})
.when('/ProjectIDCreation', {
templateUrl: '/ProjectIDCreation.html',
controller: 'headerCtrl'
})
.otherwise('/', {
templateUrl: 'AddHeader.html',
controller: 'headerCtrl'
})
}
]);

Ng-Model returning null instead of nothing

I am returning objects from a Sqlite database that sometimes returns null for some attributes of this object. For example (item.unit) is sometimes null in the database.
I got this code in my html file
<td class="item-row-quote"><span class="quote-price-text" ng-model="row.dollarPerUnitText"
id="dollarPerUnit">{{ '$/' + item.unit }}</span></td>
How can I make sure the browser display nothing for item.unit instead of displaying null.
This is my controller code
angular.module('canex')
.controller("QuoteController", ['$scope', '$routeParams', '$location', 'ProjectService', 'QuoteService', 'UploadService', 'ClientService', 'ItemService', 'ConditionService',
function ($scope, $routeParams, $location, projectService, quoteService, uploadService, clientService, itemService, conditionService) {
$scope.clientId = $routeParams.clientId;
$scope.projectId = $routeParams.projectId;
$scope.quoteId = $routeParams.quoteId;
$scope.IMG_URL = uploadService.getImageUrl();
$scope.quoteDate = new Date().getFullYear().toString().substr(2, 2);
$scope.items = [];
function _fetchQuote() {
quoteService.getQuote($routeParams.quoteId)
.then(function (response) {
$scope.quote = response.data;
}, $scope.httpErrorCallback);
}
function _fetchItems() {
itemService.getQuoteItems($routeParams.quoteId)
.then(function (response) {
$scope.items = response.data;
}, $scope.httpErrorCallback);
}
function _fetchConditions() {
conditionService.getQuoteConditions($routeParams.quoteId)
.then(function (response) {
$scope.conditions = response.data;
}, $scope.httpErrorCallback);
}
function _fetchClient() {
clientService.getClient($routeParams.clientId)
.then(function (response) {
$scope.client = response.data;
}, $scope.httpErrorCallback);
}
function _fetchProject() {
projectService.getProject($routeParams.projectId)
.then(function (response) {
$scope.project = response.data;
}, $scope.httpErrorCallback);
}
$scope.addRow = function () {
$scope.items.data.push({});
};
$scope.addCondition = function () {
if (document.getElementById("condition-page").style.display == "none") {
document.getElementById("condition-page").style.display = '';
}
$scope.conditions.data.push({})
};
$scope.removeRow = function (index) {
var itemId = $scope.items.data[index].id;
itemService.archiveItem(itemId);
$scope.items.data.splice(index, 1);
};
$scope.removeCondition = function (index) {
var conditionId = $scope.conditions.data[index].id;
conditionService.archiveCondition(conditionId);
$scope.conditions.data.splice(index, 1);
};
$scope.subtotal = function () {
var subtotal = 0;
angular.forEach($scope.items.data, function (item) {
subtotal += item.quantity * item.rate;
});
return subtotal;
};
$scope.generateQuote = function (divName) {
$scope.submitItems();
$scope.submitConditions();
if ($scope.conditions.data.length == 0) {
document.getElementById("condition-page").style.display = "none";
}
var printContents = document.getElementById(divName).innerHTML;
var popupWin;
if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
popupWin = window.open('', '_blank', 'width=600,height=800,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no');
popupWin.window.focus();
popupWin.document.write('<!DOCTYPE html><html><head>' +
'<link rel="stylesheet" type="text/css" href="../css/style.css" />' +
'</head><body onload="window.print()"><div class="reward-body">' + printContents + '</div></html>');
popupWin.onabort = function (event) {
popupWin.document.close();
popupWin.close();
}
} else {
popupWin = window.open('', '_blank', 'width=800,height=600');
popupWin.document.open();
popupWin.document.write('<html><head><link rel="stylesheet" type="text/css" href="../css/style.css" /></head><body onload="window.print()">' + printContents + '</html>');
popupWin.document.close();
}
popupWin.document.close();
return true;
};
$scope.submitItems = function () {
angular.forEach($scope.items.data, function (item) {
if (item.quote_id == undefined) {
delete item.$$hashKey;
item.quote_id = $routeParams.quoteId;
itemService.createItem(item);
}
});
};
$scope.submitConditions = function () {
angular.forEach($scope.conditions.data, function (condition) {
if (condition.quote_id == undefined) {
delete condition.$$hashKey;
condition.quote_id = $routeParams.quoteId;
conditionService.createCondition(condition);
}
})
};
_fetchItems();
_fetchConditions();
_fetchQuote();
_fetchClient();
_fetchProject();
}])
.directive('elastic', [
'$timeout',
function ($timeout) {
return {
restrict: 'A',
link: function ($scope, element) {
$scope.initialHeight = $scope.initialHeight || element[0].style.height;
var resize = function () {
element[0].style.height = $scope.initialHeight;
element[0].style.height = "" + (element[0].scrollHeight + 10) + "px";
};
element.on("input change", resize);
$timeout(resize, 0);
}
};
}
]);
You can use ng-show somthing like :
<td class="item-row-quote">
<span ng-show = "item.unit != null" class="quote-price-text" ng-model="row.dollarPerUnitText" id="dollarPerUnit">{{ '$/' + item.unit }}</span></td>
I hope that this is what you mean by nothing it is not clear.
If you have one or two properties that may have null, then you can update them with empty strings in the controller.
DefaultController.$inject = ['$http'];
function DefaultController($http) {
var vm = this;
vm.item;
function getItem() {
var config = {
transformResponse: function(data, headers) {
if (data) {
if (data.unit === null || data.unit === undefined) {
data.unit = '';
}
}
return data;
}
};
$http.get('/api/items', config)
.success(getItemCompleted);
function getItemCompleted(data) {
vm.item = data;
}
}
}
If you are having many properties that may be null and if you have control of the server side code, then see if you can handle there by returning empty arrays or empty list but not null if not then write a custom filter where you can loop through all the properties of an object and assign empty string to any property that is a falsy value

Getting the values of a returned JSON object in angular js

I am new to angular and node.js.
Basically, I have a table of items and in each row, there is a button click.
If I click the button which is edit, the details should appear in its corresponding textbox for editing.
router.route('/contacts/getone/:pk')
.get(function(req, res, next){
pg.connect(connectionString, function(err, client, done) {
//var id = {pk:req.body.pk};
var contacts = [];
console.log("get1");
console.log(req.params.pk);
var query = client.query("select * from contacts where pk=($1)", [req.params.pk]);
query.on('row', function(row) {
contacts.push(row);
});
query.on('end', function() {
done();
return res.json(contacts);
});
});
});
And this is my angular controller code.
$scope.editContact = function(id) {
contact.getone(id)
.success(function(data) {
$scope.contactlist = data;
//console.log("geone");
//document.getElementById("fname").value = $scope.contactlist.firstname;
//console.log("getall");
//console.log($scope.contactlist.firstname);
//console.log(data["firstname"]);
$scope.formData.firstname = $scope.contactlist.firstname;
$scope.formData.lastname = $scope.contactlist.lastname;
$scope.formData.address = $scope.contactlist.address;
$scope.formData.contact = $scope.contactlist.contact;
// $scope.loading = false;
});
};
Can anyone tell me how to access the values in data which is returned by my node.js code? The code I have in my angular returns undefined values like $scope.contactlist.firstname is undefined.
This is the image of when I do console.log(data);
#Rayin Dabre
----This is my the code of my controller.
angular.module('ContactsControl', [])
.controller('contactController', ['$scope', '$http', 'contact', function($scope, $http, contact) {
$scope.formData = {};
contact.get()
.success(function(data) {
console.log("getall");
$scope.contactlist = data;
// $scope.loading = false;
});
$scope.editContact = function(id) {
contact.getone(id)
.success(function(data) {
$scope.contactlist = data;
//console.log("geone");
//document.getElementById("fname").value = $scope.contactlist.firstname;
console.log(data);
//console.log($scope.contactlist.firstname);
//console.log(data["firstname"]);
$scope.formData.firstname = $scope.contactlist.firstname;
$scope.formData.lastname = $scope.contactlist.lastname;
$scope.formData.address = $scope.contactlist.address;
$scope.formData.contact = $scope.contactlist.contact;
// $scope.loading = false;
});
};
You have to define formData as object({}) or else $scope.formData will be undefined and you can not set property of undefined
Data being received from the api is not an object but an array. You need to return the data once you get the row
Server side
router.route('/contacts/getone/:pk')
.get(function(req, res, next) {
pg.connect(connectionString, function(err, client, done) {
var query = client.query("select * from contacts where pk=($1)", [req.params.pk]);
query.on('row', function(row) {
return res.json(row);
});
});
});
Client side
var data = {
$$hashKey: "008",
contact_num: 123,
email: "a#gmail.com",
firstname: "boy",
lastname: "kigwa",
pk: 2
};
$scope.formData = {};
$scope.contactlist = data;
$scope.formData.firstname = $scope.contactlist.firstname;
$scope.formData.lastname = $scope.contactlist.lastname;
$scope.formData.address = $scope.contactlist.address;
$scope.formData.contact = $scope.contactlist.contact;
alert(JSON.stringify($scope.formData));

waiting for json response in angularjs factory

I am getting closer in my quest for a JSON response. In this example, the events variable gets populated AFTER it's returned, causing a blank output. I need it to wait. I have read that a promise is the way to go... but not sure how that would work... in my console.log you can see the array but Events.all(); returns null.
.factory('Events', function($http) {
var events="";
$http.get('http://appserver.falconinet.com/events.lasso').then(function(resp) {
events = resp.data;
console.log(events);
}, function(err) {
console.error('ERR', err);
// err.status will contain the status code
})
return {
all: function() {
return events;
},
get: function(eventId) {
for (var i = 0; i < events.length; i++) {
if (events[i].id === parseInt(eventId)) {
return events[i];
}
}
return null;
}
}
})
and here is my controller:
// events
.controller('EventsCtrl', function($scope, Events) {
$scope.events = Events.all();
})
.controller('EventDetailCtrl', function($scope, $stateParams, Events) {
$scope.event = Events.get($stateParams.eventId);
})
Following will return the promise created by $http as well as caches the loading of all events.
.factory('Events', function ($http, $q) {
function loadEvents(id) {
var promise = $http.get('http://appserver.falconinet.com/events.lasso', {cache: true});
// return the promise
return promise.then(function (resp) {
var events = resp.data;
if (id) {
// returns item or promise rejection
return getEventById(id, events);
} else {
return events;
}
}).catch (function (err) {
console.log('Events error ', err);
});
}
// helper function , returns event or promise rejection
function getEventById(id, events) {
for (var i = 0; i < events.length; i++) {
if (events[i].id === parseInt(eventId)) {
return events[i];
}
}
return $q.reject('None found');
}
return {
all: function () {
return loadEvents();
},
get: function (eventId) {
return loadEvents(eventId);
}
}
});
Then in controllers you need to resove your data in the promise then callback
.controller('EventsCtrl', function($scope, Events) {
Events.all().then(function(events){
$scope.events = events;
});
})
.controller('EventDetailCtrl', function($scope, $stateParams, Events) {
Events.get($stateParams.eventId).then(function(event){
$scope.event = event;
});
})
As you mentioned, wrapping your actual process in a new promise is the way to go. In order to do so, the usage of this factory needs some tweaks. Lemme try to write a sample from your script, but I don't promise to get it working on the first try :)
.factory('Events', function($http, $q) {
return {
all: function() {
var myPromise = $q.defer();
$http.get('http://appserver.falconinet.com/events.lasso')
.then(function(resp) {
myPromise.resolve(resp.data);
}, function(err) {
myPromise.reject(err);
});
return myPromise.promise;
},
get: function(eventId) {
var myPromise = $q.defer();
$http.get('http://appserver.falconinet.com/events.lasso')
.then(function(resp) {
var events = resp.data;
for (var i = 0; i < events.length; i++) {
if (events[i].id === parseInt(eventId)) {
myPromise.resolve(events[i]);
}
}
}, function(err) {
myPromise.reject(err);
});
return myPromise.promise;
}
}
});
Besides everything, this can be improved as you placer but I found pretty straightforward to do so after knowing how to handle promises.
Using them would be like this:
// Get all
Events.all().then(function(events){
$scope.events = events;
});
// Get one
Events.get(eventId).then(function(event){
$scope.events = event;
});

AngularJS Factory Usage

.factory('MY', function($http){
return {
mustafa: function(){
var factory = {};
var url = '/uzak/remote.php?callback=JSON_CALLBACK';
var yarro = $http.get(url).success(function(response){
return response.data);
});
return yarro;
}
}
})
.controller('nbgCtrl', function() {
$scope.mangas = MY.mustafa();
})
I wanna use json data above like. But it isn't working. Could you guys help me?
You can return the promise, and then resolve it in the controller:
.factory('MY', function($http){
return {
mustafa: function() {
var url = '/uzak/remote.php?callback=JSON_CALLBACK';
return $http.get(url);
}
};
})
Finally, you have to inject the service to the controller.
.controller('nbgCtrl', function($scope, MY) {
MY.mustafa().success(function(response) {
$scope.mangas = response.data;
);
});