AngularJS $http.get in MVC5 Areas - angularjs

I have an Area named Employer in MVC5 and in the root a folder named app that contains a folder named list. In list folder I created js files and as a service factory I user this code :
angSalaryApp.factory('listService', ["$http",
function ($http) {
return {
newList: newList
};
function newList() {
return $http.get("Areas/Employer/List/newlist");
}
return {
userLists: userLists
};
function userLists() {
return $http.get("Areas/Employer/List/getlists");
}
}
]);
but newlist and userlists actions aren't called and my controller variables are undefined. it's my controller code :
angSalaryApp.controller('listController',
function ListController($scope, listService) {
$scope.list = listService.newList;
$scope.userlist = [];
$scope.count = 0;
$scope.submitForm = function () {
};
$scope.loadLists = function () {
$scope.userlist = listService.userLists;
$scope.d = "ffdgdfg";
};
$scope.updateName = function (newtitle) {
$scope.list.Name = newtitle;
};
});

You need to restructure your factory like this:
angSalaryApp.factory('listService', ["$http",
function ($http) {
return {
newList: newList,
userLists: userLists
};
function newList() {
return $http.get("Areas/Employer/List/newlist");
}
function userLists() {
return $http.get("Areas/Employer/List/getlists");
}
}
]);
...otherwise userLists will be private.

Have you tried to move the route initialization to the Area registration?
using System.Web.Mvc;
namespace MyAreaTest
{
public class MyAreaRegistration : AreaRegistration
{
public override string AreaName
{
get { return "MyArea"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Area_default",
"MyArea/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}

Related

Where to handle returning data from Angular service?

I try to handle an Angularjs 1 project by using classes, I have created class as the following
angular.module('Models').factory('Project', function (API, $rootScope) {
var Project = function() {
return new Project.fn.init();
}
// instance methods
Project.fn = Project.prototype = {
init: function() {
this.id = null,
this.name = ""
},
setId: function(id) {
this.id = id;
},
setName: function(name) {
this.name = name;
},...
Now I set the obj attr. in the same class as following:
Project.getAll = function(scopeProjects) {
return API.getAll(this).then(function(response) {
var allProjects = response.data.body;
allProjects.forEach(function (project) {
var obj = new Project();
obj.setId(project.id);
obj.setName(project.name);
scopeProjects.push(obj);
})
}, function(error) {
console.log("Fail : ", error);
});
}
my question is where to use my setters?
Do I have to handle this by returning the data to controllers or the way I use here is the best one?

Delay loading data in Angular JS

I have code like this
(function (app) {
app.controller('productListController', productListController)
productListController.$inject = ['$scope', 'apiService', 'notificationService', '$ngBootbox', '$filter'];
function productListController($scope, apiService, notificationService, $ngBootbox, $filter) {
$scope.products = [];
$scope.page = 0;
$scope.pagesCount = 0;
$scope.getProducts = getProducts;
$scope.keyword = '';
$scope.search = search;
$scope.deleteProduct = deleteProduct;
$scope.selectAll = selectAll;
$scope.deleteMultiple = deleteMultiple;
function deleteMultiple() {
var listId = [];
$.each($scope.selected, function (i, item) {
listId.push(item.ID);
});
var config = {
params: {
checkedProducts: JSON.stringify(listId)
}
}
apiService.del('/api/product/deletemulti', config, function (result) {
notificationService.displaySuccess('Deleted successfully ' + result.data + 'record(s).');
search();
}, function (error) {
notificationService.displayError('Can not delete product.');
});
}
$scope.isAll = false;
function selectAll() {
if ($scope.isAll === false) {
angular.forEach($scope.products, function (item) {
item.checked = true;
});
$scope.isAll = true;
} else {
angular.forEach($scope.products, function (item) {
item.checked = false;
});
$scope.isAll = false;
}
}
$scope.$watch("products", function (n, o) {
var checked = $filter("filter")(n, { checked: true });
if (checked.length) {
$scope.selected = checked;
$('#btnDelete').removeAttr('disabled');
} else {
$('#btnDelete').attr('disabled', 'disabled');
}
}, true);
function deleteProduct(id) {
$ngBootbox.confirm('Are you sure to detele?').then(function () {
var config = {
params: {
id: id
}
}
apiService.del('/api/product/delete', config, function () {
notificationService.displaySuccess('The product hase been deleted successfully!');
search();
}, function () {
notificationService.displayError('Can not delete product');
})
});
}
function search() {
getProducts();
}
function getProducts(page) {
page = page || 0;
var config = {
params: {
keyword: $scope.keyword,
page: page,
pageSize: 20
}
}
apiService.get('/api/product/getall', config, function (result) {
if (result.data.TotalCount == 0) {
notificationService.displayWarning('Can not find any record.');
}
$scope.products = result.data.Items;
$scope.page = result.data.Page;
$scope.pagesCount = result.data.TotalPages;
$scope.totalCount = result.data.TotalCount;
}, function () {
console.log('Load product failed.');
});
}
$scope.getProducts();
}
})(angular.module('THTCMS.products'));
So my problem is when i loading data the application take me some time to load data.
I need load data as soon as
Is the any solution for this?
Since you are loading data via api call, there will be a delay. To handle this delay, you should display a loading screen. Once the data is loaded, the loading screen gets hidden and your main screen is visible. You can achieve this using $http interceptors.
See : Showing Spinner GIF during $http request in angular
The api-call is almost certainly causing the delay. Data may be received slowly via the api-call so you could display any sort of loading text/image to notify the use that the data is being loaded.
If u want the data ready at the time when controller inits, u can add a resolve param and pass the api call as a $promise in the route configuration for this route.

Restangular - Specific Function to Specific Factory

I'm working with restangular and so far, everything works very well, but, i have this issue that cannot resolve.
I define a abstract repository with the basic operations like this:
app.factory('AbstractRepository', [
function(){
function AbstractRepository(restangular, route) {
this.restangular = restangular;
this.route = route;
};
AbstractRepository.prototype = {
getList: function (params) {
return this.restangular.all(this.route).getList(params).$object;
},
get: function (id) {
return this.restangular.one(this.route, id).get();
},
getView: function (id) {
return this.restangular.one(this.route, id).one(this.route + 'view').get();
},
update: function (updatedResource) {
return updatedResource.put().$object;
},
create: function (newResource) {
return this.restangular.all(this.route).post(newResource);
},
remove: function (object) {
return this.restangular.one(this.route, object.id).remove();
},
};
AbstractRepository.extend = function (repository) {
repository.prototype = Object.create(AbstractRepository.prototype);
repository.prototype.constructor = repository;
}
return AbstractRepository;
}
]);
And the specific respository:
app.factory('ServiceRepository', ['Restangular', 'AbstractRepository',
function (restangular, AbstractRepository) {
function ServiceRepository() {
//restangular.setBaseUrl("http://192.168.0.144:8080/api/rest/services/");
AbstractRepository.call(this, restangular,'http://192.168.0.144:8080/api/rest/services/');
}
AbstractRepository.extend(ServiceRepository);
return new ServiceRepository();
}
And i call the methods :
ServiceRepository.getList();
And now i want to implement and function (getServicesByOperatorId) that only works in the specific repository, not in the abstract. So i can call it like this:
ServiceRepository.getServicesByOperatorId({"operatorId":7});
If i define the function in the prototype of the abstract it works, but i want i way to define in the specific.
Thank you very much for your time.
Finally i find a way to do what i want:
In the specific factory define the prototype and extend from the abstract prototype like this:
ServiceRepository.prototype = {
getServicesByOperatorId: function (id) {
return this.restangular.all(this.route + 'getServicesByOperatorId').getList(id).$object;
}
}
angular.extend(ServiceRepository.prototype, AbstractRepository.prototype);
And in the abstract repository, remove this definition:
AbstractRepository.extend = function (repository) {
repository.prototype = Object.create(AbstractRepository.prototype);
repository.prototype.constructor = repository;
}
No i can access to de getList() method and the getServicesByOperatorId().

AngularJS local storage - initialize app retrieving local-stored data

I'm pretty new to angular and I'm trying to avoid losing items added on a simple cart application when the user refreshes the page.
I'm using angularLocalStorage (https://github.com/agrublev/angularLocalStorage) but don't know how to retrieve it back the content.
My lines:
var myApp = angular.module('ionicApp', ['ionic','angularLocalStorage']);
myApp.factory('prodottiData', function($http) {
return {
getFooOldSchool: function(callback) {
$http.get('http://192.168.1.128/hongkongapp/?json=get_recent_posts&post_type=product&custom_fields=all').success(callback);
}
}
});
myApp.factory('DataService', function() {
var myCart = new shoppingCart("AngularStore");
return {
cart : myCart
};
});
myApp.controller('MyController', function MyController ($scope, storage, $ionicSideMenuDelegate, prodottiData, DataService, $sce) {
$scope.toggleLeft = function() {
$ionicSideMenuDelegate.$getByHandle('mainMenu').toggleLeft();
};
$scope.toggleMySecondMenuLeft = function() {
$ionicSideMenuDelegate.$getByHandle('mySecondMenu').toggleLeft();
};
//adding menu data to the scope object
prodottiData.getFooOldSchool(function(data) {
$scope.menu = data;
});
//adding the cart to the scope object
$scope.cart = DataService.cart;
$scope.to_trusted = function(html_code) {
return $sce.trustAsHtml(html_code);
}
images = $scope.menu;
$scope.showloader = function(){
$scope.shownImage = this.post.thumbnail_images.full.url;
$scope.itemDesc = this.post.content;
$scope.itemPrice = this.post.custom_fields._price[0];
$scope.productName = this.post.title;
$scope.skuProdotto = this.post.id;
}
});
Now, if I check local storage on the console I can see something is really stored, but I miss the way to re-populate the cart at startup.
Any help would be great!
why not just using browser local storage ?
you can add it to your services.js as a new service and just used that.
var storeService = myAppServices.factory('storeService', function() {
var service =
{
setClientData:function(client_details)
{
window.localStorage.setItem( "client_data", JSON.stringify(client_details) );
client_data = client_details;
},
getClientData:function()
{
if (client_data == null)
{
client_data = JSON.parse(window.localStorage.getItem("client_data"));
}
return client_data;
}
}
var client_data = null;
return service;
});
From the documentation, to retrieve, it's storage.get('key')
So, to check after refresh:
if (storage.get('someKey')){
$scope.retrieved_value = storage.get('someKey');
}else{
// whatever
}
You can use localStorage instead windows.localStorage.
if(typeof(Storage)!=="undefined")
{
// Code for localStorage/sessionStorage.
var hello = "Hello World!!";
localStorage.setItem("hello",hello);
// get string
console.log(localStorage.getItem("hello")); // will return 'Hello World!!'
var me = {name:'abel',age:26,gender:'male'};
localStorage.setItem("user", JSON.stringify(me));
//fetch object
console.log(localStorage.getItem("user")); // will return {"name":"myname","age":99,"gender":"myGender"}
var objetos = JSON.parse(localStorage.getItem("user"));
console.log(objetos.name);
}
else
{
// Sorry! No Web Storage support..
}

Variables between factories in angular.js

I'm currently learning angular and have hit a roadblock.
The second factory (shown below) makes an http request like this: http://example.com/api/get_post/?post_id=7129&callback=JSON_CALLBACK');
I want the post ID to be a variable. So depending on which blog title is clicked, I can pass the correct variable into that http request.
In other words, I guess I want to take a result from the first factory (blogAPIservice) and use it in the second factory.
Makes sense??
<!-- FACTORIES -->
angular.module('blogApp.services',[])
.factory('blogAPIservice',function($http) {
var blogAPI = [];
var blogs = $http.jsonp('http://example.com/api/get_recent_posts/?count=10&callback=JSON_CALLBACK');
blogs.success(function(data) {
$.each(data.posts, function(i, blog) {
var fromNow = moment(blog.date).fromNow();
blogAPI.push({
url: blog.url,
title: blog.title,
excerpt: blog.excerpt,
date : fromNow,
id: blog.id
})
});
});
var factory = {};
factory.getBlogs = function () {
return blogAPI;
};
return factory;
})
.factory('singlePostService',function($http) {
var singleAPI = [];
var postID = '7129';
var singlePost = $http.jsonp('http://example.com/api/get_post/?post_id=7129&callback=JSON_CALLBACK');
singlePost.success(function(data) {
singleAPI.push({
title: data.post.title,
content: data.post.content
})
});
var factory = {};
factory.getSinglePost = function () {
return singleAPI;
};
return factory;
})
And here are the controllers:
angular.module('blogApp.controllers', [])
.controller('resultsController',function($scope, blogAPIservice) {
$scope.keywordFilter = null;
$scope.blogs = [];
init();
function init() {
$scope.blogs = blogAPIservice.getBlogs();
}
function grabID() {
$(this).attr('rel');
}
})
.controller('singlePostController',function($scope, singlePostService) {
$scope.keywordFilter = null;
$scope.singlePost = [];
init();
function init() {
$scope.singlePost = singlePostService.getSinglePost();
}
})
And finally the markup:
<li ng-repeat="blog in blogs">
{{ blog.title }}
</li>
You can inject the first service into the second one like this:
.factory('singlePostService',function($http, blogAPIservice) {
//Do something with blogAPIservice
}
For more information about depenency injection read the docs

Resources