Use data from factory in controller in angularjs - angularjs

I am very new to AngularJS.
I want to pass an array data from my app factory to app controller.
Here is my app.factory code.
App.factory('buyFactory', ['$http', function($http) {
factory.Search = function(scope, d) {
var data = scope.search;
scope.CarsData = [];
all_cars = [];
scope.isLoading = true;
$http.post(ajaxurl + '?action=search_car', d)
.success(function(response) {
angular.forEach(response, function(c) {
c.price = parseFloat(c.price);
c.driven = parseFloat(c.driven);
c.year = parseFloat(c.year);
});
angular.forEach(response, function(value, key) {
all_cars.push(value);
scope.CarsData = all_cars;
scope.TotalItems = scope.CarsData.length;
scope.isLoading = false;
})
.error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
scope.isLoading = false;
});
}
return factory;
}]);
and this is app.controller as
App.controller('buyController', ['$scope', '$http', 'buyFactory', '$filter', function($scope, $http, buyFactory, $filter) {
$scope.CarsScroll = buyFactory.Search.CarsData();
$scope.loadMore = function() {
var last = $scope.CarsScroll[$scope.CarsScroll.length - 1];
for (var i = 1; i <= 3; i++) {
$scope.CarsScroll.push(last + i);
}
};
//scroll
}]);
I want to use output obtained from factory i.e. CarsData as a variable in my app controller. But I am not able to get it. I have tried using services also. Is there method to use array data in a simplest way.

Your syntax is completely broken, i would recommend following any course of AngularJS. As for how to correctly do what you are trying to would look something like this
app.factory('buyFactory', ['$http', '$q', function($http, $q) {
var factory = {
search: function(d) {
return $q(function(resolve, reject) {
$http.post(ajaxurl + '?action=search_car', d).then(function(response) {
angular.forEach(response, function(c) {
c.price = parseFloat(c.price);
c.driven = parseFloat(c.driven);
c.year = parseFloat(c.year);
});
var carsData = [];
angular.forEach(response, function(value, key) {
carsData.push(value);
})
var result = {
carsData: carsData,
total: carsData.length
}
resolve(result);
}, function(error) {
reject(error);
})
});
}
}
return factory;
}]);
app.controller('buyController', ['$scope', '$http', 'buyFactory', '$filter', function($scope, $http, buyFactory, $filter) {
buyFactory.search().then(function(result) {
var cars = result.carsData;
var total = result.total;
})
}]);
Note: i do not know what the d parameter is for neither why the angular.forEach statements so it might not be fully functional. But this is more as guideline for how your factory should look and be used.

Related

Cleaning JSON data

I am trying to clean the JSON data i have i.e. remove the N/A and null data. I am trying to use $.each to clean the data however it has no effect on the data.
.controller('APICtrl', function($scope, $http, $localstorage, $window, $state, $sce) {
// Search function
//var offices = [];
var n;
$scope.query = {}
$scope.queryBy = '$'
// gets the data from offices.json
$http.get('js/offices.json').then(function(resp) {
console.log('Success', resp);
$scope.offices = $.each(resp.data.office, function(key,value){
//console.log(value);
if(value==""||value==null){
delete resp.data.office[key];
}
});
//console.log(offices)
}, function(err) {
console.error('ERR', err);
// err.status will contain the status code
});
instean jquery functions
$scope.offices = $.each(resp.data.office, function(key,value){
use standart angular functions
$scope.offices = angular.forEach(resp.data.office, function(key,value){
https://docs.angularjs.org/api/ng/function/angular.forEach
Do you have jQuery included? Otherwise my guess is that you're getting an error that is being silenced because it's inside of a then. This should work:
.controller('APICtrl', function($scope, $http, $localstorage, $window, $state, $sce) {
// Search function
//var offices = [];
var n;
$scope.query = {};
$scope.queryBy = '$';
// gets the data from offices.json
$http.get('js/offices.json').then(function(resp) {
console.log('Success', resp);
var office = resp.data.office;
angular.forEach(office, function(value, key){
if (value == "" || value == null) {
delete office[key];
}
});
$scope.offices = office;
//console.log(offices)
}, function(err) {
console.error('ERR', err);
// err.status will contain the status code
});
});

Avoid repetition in Angular controller

I'm an angular newbie and I'm writing an Ionic app.
I finished my app and am trying to refactor my controller avoiding code repetition.
I have this piece of code that manages my modal:
angular.module('starter')
.controller('NewsCtrl', function($scope, content, $cordovaSocialSharing, $timeout, $sce, $ionicModal){
$scope.news = content;
content.getList('comments').then(function (comments) {
$scope.comments = comments;
});
$scope.addComment = function() {
};
$scope.shareAnywhere = function() {
$cordovaSocialSharing.share("Guarda questo articolo pubblicato da DDay", "Ti stanno segnalando questo articolo", content.thumbnail, "http://blog.nraboy.com");
};
$ionicModal.fromTemplateUrl('templates/comments.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.showComment = function() {
$scope.modal.show();
};
// Triggered in the login modal to close it
$scope.closeComment = function() {
$scope.modal.hide();
};
$scope.$on('modal.shown', function() {
var footerBar;
var scroller;
var txtInput;
$timeout(function() {
footerBar = document.body.querySelector('#commentView .bar-footer');
scroller = document.body.querySelector('#commentView .scroll-content');
txtInput = angular.element(footerBar.querySelector('textarea'));
}, 0);
$scope.$on('taResize', function(e, ta) {
if (!ta) return;
var taHeight = ta[0].offsetHeight;
if (!footerBar) return;
var newFooterHeight = taHeight + 10;
newFooterHeight = (newFooterHeight > 44) ? newFooterHeight : 44;
footerBar.style.height = newFooterHeight + 'px';
scroller.style.bottom = newFooterHeight + 'px';
});
});
});
I have added this same code in 6 controllers.
Is there a way to avoid the repetition?
Probably what you are looking for is an angular service. This component is a singleton object, that you inject in every controller you need to execute this code.
Angular Services
Regards,
Below is an example of a service I created to retrieve address data from a Json file. Here is the working Plunk. http://plnkr.co/edit/RRPv2p4ryQgDEcFqRHHz?p=preview
angular.module('myApp')
.factory('addressService', addressService);
addressService.$inject = ['$q', '$timeout', '$http'];
function addressService($q, $timeout, $http) {
var addresses = [];
//console.log("Number of table entries is: " + orders.length);
var promise = $http.get('address.data.json');
promise.then(function(response) {
addresses = response.data;
// console.log("Number of table entries is now: " + orders.length);
});
return {
GetAddresses: getAddresses
};
function getAddresses() {
return $q(function(resolve, reject) {
$timeout(function() {
resolve(addresses);
}, 2000);
});
}
}
Here's an example of how I added dependencies for it and another service to my controller (This is NOT the only way to do dependency injection, but is my favorite way as it is easier to read). I then called my addressService.GetAddresses() from within my controller.
var app = angular.module('myApp', ['smart-table']);
app.controller('TableController', TableController);
TableController.$inject = [ "orderService", "addressService"];
function TableController( orderService, addressService) {
addressService.GetAddresses()
.then(function(results) {
me.addresses = results;
// console.log(me.addresses.length + " addresses");
},
function(error) {})
.finally(function() {
me.loadingAddresses = false;
});
});}
I also had to include my .js tag in a script element on my index.html.
<script src="addressdata.service.js"></script>

Passing page number param for infinite-scroll to return more results from the backend

I'm using infinite-scroll and I want to request more data using $http. So next page / next 10 results etc.
This is my current working code (I put this in a factory as I read on another post somewhere that this was a good idea, I'm now thinking a service might be better but I'm not sure yet):
angular.module('hotels', [])
.factory('hotels', function($http) {
var hotels = {};
hotels.get = function(callback) {
$http.get('/php/hotels.php').success(function(data) {
callback(data);
});
};
return hotels;
});
angular.module('app', ['hotels', 'infinite-scroll'])
.controller('hotelsCtrl', function ($scope, hotels){
hotels.get(function (data) {
$scope.hotels = data.results;
})
});
How do I pass back a param page=3 and have the backend return more results?
I thought it might look something like this but its not working.:
angular.module('hotels', [])
.factory('hotels', function($http) {
var hotels = {};
hotels.get = function(callback) {
$http.get('/php/hotels.php?page='+$scope.page).success(function(data) {
callback(data);
});
};
return hotels;
});
angular.module('app', ['hotels', 'infinite-scroll'])
.controller('hotelsCtrl', function ($scope, hotels){
$scope.page = $scope.page + 1;
hotels.get({page: $scope.page}, function (data) {
$scope.hotels.push.apply($scope.hotels, data.results);
})
});
Any ideas?
This does the job:
angular.module('hotels', [])
.factory('hotels', function($http) {
var hotels = {};
hotels.get = function(params, callback) {
$http.get('/php/hotels.php', {params: {page: params.page}}).success(function(data) {
callback(data);
});
};
return hotels;
});
angular.module('app', ['hotels', 'infinite-scroll'])
.controller('hotelsCtrl', function ($scope, hotels){
$scope.page = 1;
$scope.addMoreItems = function() {
$scope.hotels=[];
hotels.get({page: $scope.page}, function (data) {
//$scope.hotels.push(data.results);
for (var i = 0; i < data.length; i++) {
$scope.hotels.push(data[i]);
}
$scope.page+=1;
})
}
});

AngularJS $http.post method doesn't sending data to Grails Action

My Grails application doesn't receiving data from angularjs post request.
My AngularJS Controller is:
module.controller('MemberCtrl', ['$scope', '$http',
function ($scope, $http) {
$scope.submitForm = function () {
$http.post(uri + "receiveNewMember", $scope.member)
.success(function (data) {
console.log("Data Sent With Success! " + data);
})
.error(function (data) {
console.log("Fail");
});
};
}]);
My Grails Action is:
def receiveNewMember(){
render text: params.name
}
The Debugger Stops into action. But params variable hasn't any data but controller and action.
Someone knows how can I fix this?
The Post Data can be accessed via request.JSON in Grails Controller.
You can do something like this to emulate the way grails works:
post query parameters like jQuery
Also I created a Serializer factory to serialize any kind of javascript object to the expected way on grails:
(function() {
'use strict';
angular.module('app').factory('Serializer', function ($filter) {
function SerializerService(){}
var serializerService = new SerializerService();
serializerService.excludedProperties = ['$$hashKey'];
SerializerService.prototype.serialize = function(object){
var results = {};
this.serializeObject(results, object, "");
return results;
};
SerializerService.prototype.serializeObject = function(results, object, nameAtTheMoment){
if($.isArray(object)){
var array = object;
for (var i=0; i<object.length; i++){
var newNameAtTheMoment = nameAtTheMoment + "[" + i.toString() + "]";
this.serializeObject(results, array[i], newNameAtTheMoment)
}
}
else{
if(Object.prototype.toString.call( object ) === "[object Object]"){
var i=0;
for(var property in object){
if (object.hasOwnProperty(property) && this.excludedProperties.indexOf(property) == -1) {
var newNameAtTheMoment;
if(nameAtTheMoment !== "")
newNameAtTheMoment = nameAtTheMoment + "." + property;
else
newNameAtTheMoment = property;
this.serializeObject(results, object[property], newNameAtTheMoment);
i++;
}
}
}
else{ //the object is a simple value
if(Object.prototype.toString.call(object) === '[object Date]'){
var dateServerFormat = window.appConfig.dateServerFormat;
results[nameAtTheMoment] = $filter('date')(object, dateServerFormat);
}
else
results[nameAtTheMoment] = object;
}
}
};
return serializerService;
});
})();
And following the first link description you can do something like this:
angular.module('app', [...])
.config(function ($provide, $httpProvider) {
var serializer;
// Trick to inject dependencies on the config function.
$provide.factory('FactoryInjector', function () {
return {
setSerializer: function(serializerParam){
serializer = serializerParam;
}
};
});
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
$httpProvider.defaults.transformRequest = [function(data) {
return angular.isObject(data) && String(data) !== '[object File]' ? $.param(serializer.serialize(data)) : data;
}];
})
.run(function ($rootScope, $state, $stateParams, Serializer, FactoryInjector) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
FactoryInjector.setSerializer(Serializer);
});

"undefined is not a function" error using angularFire

i am trying to display data from firebase and i have below code. I already declared firebase dependency for my app.
.controller('AdvMainCtrl', ['$scope', 'dataLoad',
function($scope, dataLoad, $route, $routeParams, $location, $resource, angularFire) {
var categoryPromise = dataLoad.loadCategories($scope, 'categories'),
tmPromise = dataLoad.loadTransportationMode($scope, 'tModes'),
tourPromise = dataLoad.loadAdventures($scope, 'tours');
categoryPromise.then(function() {
console.log('data loaded');
});
$scope.$watch('category', function() {
if (typeof $scope.category === 'undefined') return;
console.log('category changed');
console.log($scope.category.name);
});
$scope.$watch('tMode', function() {
if (typeof $scope.tMode === 'undefined') return;
console.log('tm changed');
//console.log($scope.transportationMode.name);
});
var ref = new Firebase("https://wpladv.firebaseio.com/adventure");
$scope.tours = [];
angularFire(ref, $scope, "tours");
}
])
in the console i see the error occurring at angularFire(ref, $scope, "tours"); statement. I am not sure how to fix this.
the entire code in my controller is
.controller('AdvMainCtrl', ['$scope', 'dataLoad',
function($scope, dataLoad, $route, $routeParams, $location, $resource, angularFire) {
var categoryPromise = dataLoad.loadCategories($scope, 'categories'),
tmPromise = dataLoad.loadTransportationMode($scope, 'tModes'),
tourPromise = dataLoad.loadAdventures($scope, 'tours');
categoryPromise.then(function() {
console.log('data loaded');
});
$scope.$watch('category', function() {
if (typeof $scope.category === 'undefined') return;
console.log('category changed');
console.log($scope.category.name);
});
$scope.$watch('tMode', function() {
if (typeof $scope.tMode === 'undefined') return;
console.log('tm changed');
//console.log($scope.transportationMode.name);
});
var ref = new Firebase("https://wpladv.firebaseio.com/adventure");
$scope.tours = [];
angularFire(ref, $scope, "tours");
}
])
the error is showing at "var categoryPromise = dataLoad.loadCategories($scope, 'categories')," statement
i have the following code in my api js file.
angular.module('localAdventuresApp')
.factory('dataLoad', ['angularFire',
function(angularFire) {
var dbUrl = 'https://wpladv.firebaseio.com/';
return {
loadCategories: function(scope, items) {
var cat = '/category';
return angularFire(dbUrl + cat, scope, items, []);
},
loadTransportationMode: function(scope, items) {
var cat = '/transportMode';
return angularFire(dbUrl + cat, scope, items, []);
},
loadAdventures: function(scope, items) {
var cat = '/adventures';
return angularFire(dbUrl + cat, scope, items, {});
}
}
}
])
the error is being displayed in the "return angularFire(dbUrl + cat, scope, items, []);" statement here. The error which i am seeing in my console is "Error: Please provide a Firebase reference instead of a URL, eg: new Firebase(url)".
you need to inject the dependencies to your controller
.controller('AdvMainCtrl', ['$scope', 'dataLoad', '$route', '$routeParams', '$location', '$resource', 'angularFire',
function($scope, dataLoad, $route, $routeParams, $location, $resource, angularFire) {
// your code here
}
])
the error "Please provide a Firebase reference instead of a URL, eg: new Firebase(url)" was occuring because i had angularfire version > 0.3.0. All i had to do was to change dbUrl + cat to new Firebase(dbUrl + cat). That fixed the issue. Thank you all for your valuable suggestions.
code after change
angular.module('localAdventuresApp')
.factory('dataLoad', ['angularFire',
function(angularFire) {
var dbUrl = 'https://wpladv.firebaseio.com';
return {
loadCategories: function(scope, items) {
var cat = '/category';
console.log(dbUrl);
var ref = new Firebase(dbUrl + cat);
return angularFire(ref, scope, items, []);
},
loadTransportationMode: function(scope, items) {
var cat = '/transportMode';
var ref = new Firebase(dbUrl + cat);
return angularFire(ref, scope, items, []);
},
loadAdventures: function(scope, items) {
var cat = '/adventure';
var ref = new Firebase(dbUrl + cat);
return angularFire(ref, scope, items, {});
}
}
}
])

Resources