I started using angular a week ago and I have been banging me head trying to solve this problem. I have a service that wraps $http because multiple controllers call the same url. There is one page that has a lot of business logic on the server on a post so I want to call $route.reload(). It seems to work because after vm.saveItem() the controller is reinitialized, but the $http.get() never sends the signal to the server for the new data. What am I doing wrong?
myModule.factory("itemRepository", function ($http) {
var baseUrl = "/api/inventory";
return {
getLocations: function (itemName) {
return $http({
url: baseUrl + "/" + itemName + "/locators",
method: "GET",
cache: false
});
},
addNewLocator: function (itemName, newLocator) {
return $http.post(baseUrl + "/" + itemName + "/locators", newLocator);
}
};
});
// itemEditorController.js
(function () {
"use strict";
angular.module("app-inventoryitems")
.controller("itemEditorController", itemEditorController);
function itemEditorController($routeParams, $route, itemRepository) {
// initialize vars
var vm = this;
vm.itemName = $routeParams.itemName;
vm.errorMessage = "";
// Models
vm.items = [];
vm.isBusy = true;
vm.newLocator = {};
vm.newLocator.name = vm.itemName;
// PROBLEM HERE, does not call server after post new data
// and $route.reload() was called
itemRepository
.getLocations(vm.itemName)
.then(function (response) {
angular.copy(response.data, vm.items);
}, function (err) {
vm.errorMessage = "Failed to load batches.";
})
.finally(function () {
vm.isBusy = false;
});
vm.saveItem = function () {
vm.isBusy = true;
itemRepository.addNewLocator(vm.itemName, vm.newLocator)
.then(function (response) {
vm.newLocator = {};
$route.reload();
}, function (error) {
vm.errorMessage = "Failed to save new item.";
})
.finally(function () {
vm.isBusy = false;
})
}
}
})();
Try to add dynamic parameter to your request:
$http({
url: baseUrl + "/" + itemName + "/locators",
method: "GET",
cache: false,
params: {
r: Math.random().toString(16).substr(2)
}
});
If issue was solved, need looking for HTTP Caching policies.
Google for necessary server-side headers.
Related
During loading of the partial Html with controller, my function named $scope.actionViewVisitors() is recognized and runs without errors. But whenever I use it inside another function on the same controller, it gives me an error:
TypeError: $scope.actionViewVisitors is not a function. Please see my code below:
angular.module("Visitor.controller", [])
// ============== Controllers
.controller("viewVisitorController", function ($scope, $rootScope, $http, viewVisitorService, viewAccountService, DTOptionsBuilder) {
$scope.visitorList = null;
$scope.viewAccountDetail = null;
$scope.avatar = null;
$scope.visitorDetail = null;
$scope.visitorBtn = "Create";
$scope.actionViewAccount = function () {
$scope.actionViewAccount = viewAccountService.serviceViewAccount()
.then(function (response) {
$scope.viewAccountDetail = response.data.account;
$scope.avatar = "../../avatars/" + response.data.account.AccountId + ".jpg";
})
}
$scope.dtOptions = DTOptionsBuilder.newOptions()
.withDisplayLength(10)
.withOption('bLengthChange', false);
// THIS ONE IS NOT RECOGNIZED
$scope.actionViewVisitors = function () {
$scope.actionViewVisitors = viewVisitorService.serviceViewVisitors()
.then(function (response) {
debugger;
$scope.visitorList = response.data.visitorList;
});
}
// I DON'T GET ANY ERROR HERE
$scope.actionViewVisitors();
$scope.actionViewAccount();
$scope.createVisitor = function () {
$scope.statusMessage = null;
if ($scope.visitorBtn == "Create") {
$scope.createVisitor = viewVisitorService.serviceCreateVisitor($scope.visitorDetail)
.then(function (response) {
if (response.data.response == '1') {
bootbox.alert({
message: "Successfully created a new visitor.",
size: 'small',
classname: 'bb-alternate-modal'
});
} else if (response.data.response == '0') {
bootbox.alert({
message: "Failed in creting visitor.",
size: 'small',
classname: 'bb-alternate-modal'
});
}
});
debugger;
$scope.visitorDetail = undefined;
// I GET THE ERROR WHEN I CALL THIS METHOD
$scope.actionViewVisitors();
}
}
})
// ============== Factories
.factory("viewVisitorService", ["$http", function ($http) {
var fac = {};
fac.serviceViewVisitors = function () {
return $http({
url: '/Visitor/ViewVisitors',
method: 'get'
});
}
fac.serviceCreateVisitor = function(visitor) {
return $http({
url: '/Visitor/CreateVisitor',
data: { visitor: visitor },
method: 'post'
});
}
return fac;
}])
You are overwriting the function with Promise in the following line, thus the error is correct
$scope.actionViewVisitors = function () {
$scope.actionViewVisitors = viewVisitorService.serviceViewVisitors()
.then(function (response) {
$scope.visitorList = response.data.visitorList;
});
}
Remove $scope.actionViewVisitors =
$scope.actionViewVisitors = function () {
viewVisitorService.serviceViewVisitors()
.then(function (response) {
$scope.visitorList = response.data.visitorList;
});
}
On the first call to the function you are changing it from a function to a Promise. Maybe you want to be returning the result instead?
$scope.actionViewVisitors = function () {
return viewVisitorService.serviceViewVisitors()
.then(function (response) {
debugger;
$scope.visitorList = response.data.visitorList;
});
}
I am trying to make sync calls using a factory pattern.
$scope.doLogin = function (username, password, rememberme) {
appKeyService.makeCall().then(function (data) {
// data = JSON.stringify(data);
debugAlert("login controller app key service"+data);
var appkeyvalue = data.d.appkey;
sessionConfigurationService.setBasicToken(appkeyvalue);
loginService.makeCall(username, password, rememberme).then(function (accessTokenData) {
if (accessTokenData.access_token !== "")
{
sessionConfigurationService.setAccessTokenData(accessTokenData.access_token);
userPreferencesService.makeCall().then(function (userPreferencesData) {
if (userPreferencesData.d.userId !== "")
{
sessionConfigurationService.setUserPreferences(userPreferencesData.d);
// $window.location.href = '/base.html';
}
});
}
});
});
};
My appKeyService factory is
app.factory('appKeyService', function ($q, authenticatedServiceFactory, configurationService) {
var deffered = $q.defer();
var service = {};
service.makeCall = function () {
debugAlert("appKeyService async method request start");
authenticatedServiceFactory.makeCall("GET", configurationService.getAppKeyURL(), "", "").then(function (data) {
debugAlert("appKeyService async method response")
deffered.resolve(data);
});
return deffered.promise;
};
return service;
});
My authenticated service factory is
app.factory('authenticatedServiceFactory', function ($http, $q, sessionConfigurationService) {
var deffered = $q.defer();
var service = {};
service.makeCall = function (methodType, URL, data, authType) {
var headerValue = "";
if (authType === "Basic") {
headerValue = sessionConfigurationService.getBasicToken();
} else if (authType === "Bearer") {
headerValue = sessionConfigurationService.getBearerToken();
}
var config = {headers: {
'Authorization': headerValue,
'Accept': 'application/json;odata=verbose',
},
withCredentials: true,
async: false
};
if (methodType === "GET") {
$http.get(URL, data, config)
.then(function (getData) {
debugAlert("GET method response" + JSON.stringify(getData));
deffered.resolve(getData.data);
}, function (error) {
debugAlert("GET method response error" + JSON.stringify(error));
deffered.reject(error);
});
}
else if (methodType === "POST") {
$http.post(URL, data, config)
.then(function (putData) {
debugAlert("POST method response" + JSON.stringify(putData));
deffered.resolve(putData.data);
}, function (error) {
debugAlert("POST method response error" + JSON.stringify(error));
deffered.reject(error);
});
}
else if (methodType === "DELETE") {
$http.delete(URL, data, config)
.then(function (deleteData) {
debugAlert("DELETE method response" + JSON.stringify(deleteData));
deffered.resolve(deleteData.data);
}, function (error) {
debugAlert("DELETE method response error" + JSON.stringify(error));
deffered.reject(error);
});
}
else if (methodType === "PUT") {
$http.put(URL, config)
.then(function (putData) {
debugAlert("PUT method response" + JSON.stringify(putData));
deffered.resolve(putData.data);
}, function (error) {
debugAlert("PUT method response error" + JSON.stringify(error));
deffered.reject(error);
});
}
return deffered.promise;
};
return service;
});
But I don't see the service calls are made in sync. So the "then" part in the controller is not executing after we receive the response. Its executing one after the other. How can I make that happen.
#Frane Poljak
Thank you for your comment. I just brought
var deffered = $q.defer();
inside the makeCall method and its working as I wanted now. Thank you!
app.factory('appKeyService', function ($q, authenticatedServiceFactory, configurationService) {
var service = {};
service.makeCall = function () {
var deffered = $q.defer();
debugAlert("appKeyService async method request start");
authenticatedServiceFactory.makeCall("GET", configurationService.getAppKeyURL(), "", "").then(function (data) {
debugAlert("appKeyService async method response")
deffered.resolve(data);
});
return deffered.promise;
};
return service;
});
I have a JSON source and want to get results from it with a post request.
When I test with POSTMAN extension in chorme it works really well. But when I do that with angularJS the page keep loading and chrome consoles shows errors.
My code is here:
angular.module('loginApp', []).controller('loginController', function ($scope, $http) {
$scope.userName = '';
$scope.userPass = '';
$scope.output = function () {
var params = JSON.stringify({
username: '******',
password: '******'
});
$http({url: "http://xx.xx.xx.xx/api/user/login.json",
method: 'POST',
data: params,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}).then(function (response) {
return response;
});
};
});
Any help would be appreciated :)
try this, and after post error if occured:
var LoginApp = angular.module('loginApp', []);
LoginApp.controller('loginController', function ($scope, $common) {
$scope.userName = '';
$scope.userPass = '';
$scope.output = function () {
var params = JSON.stringify({
username: '******',
password: '******'
});
$common.ajax("http://xx.xx.xx.xx/api/user/login.json", params, "POST").then(function (response) {
console.log(response);
return response;
});
};
});
LoginApp.factory("$common", function($http, $q) {
function ajax(url, param, method) {
var request = $http({
method: method,
url: url,
data:param
});
var promise = request.then(
function(response) {
return(response.data);
},
function(response) {
console.log("Ocurred error: " + response);
return($q.reject("Something went wrong"));
}
);
return promise;
}
return({
ajax:ajax
});
});
Try this:
$scope.output = function () {
var params = {
username: '******',
password: '******'
};
$http.post("http://xx.xx.xx.xx/api/user/login.json", params)
.then(function (response) {
return response;
});
};
Also you should move your http request to a service. It's a bad practice put it in a controller.
My angular code:
angular.module('MyApp',[]).
controller('ProductController', function ($scope, $http) {
$scope.Product = {};
$scope.categoryList = null;
$scope.LoadCategory = function () {
$scope.a = 'sss';
$http.get('/Product/GetAllCategory/')
.success(function (data) {
if (data.success == true)
{
console.log = (data.data);
$scope.categoryList = data.data;
}
else {
alert('aws');
}
})
.error(function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest + ": " + textStatus + ": " + errorThrown, 'Error!!!');
})
};
});
and I fetched data using $http.get() from this server side code
public JsonResult GetAllCategory()
{
//List<tblCategory> categories = new List<tblCategory>();
try
{
using (CurtainHomesDBEntities dc = new CurtainHomesDBEntities())
{
var categories = dc.tblCategory.Select(a => new { a.Id, a.CatagoryName }).ToList();
return Json(new { data = categories, success = true }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
return Json(ex);
}
}
I debugged using firebug. It fetched data from server side and inserted to $scope.categoryList. But after coming the debug outside of if(data.success==true), $scope.categoryList is undefined.
What is the problem here? I could not find out.
$http.get('/Product/GetAllCategory/') returns an HttpPromise.
I would use the following (from angularjs documentation here)
// Simple GET request example :
$http.get('/someUrl').
then(function(response) {
// this callback will be called asynchronously
// when the response is available
}, function(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
I have a new userContext.js file which attempts to create a new service entitle "userService". This service in turn will communicate with the server and return some environmental settings, as well as a user session ID.
This all works fine when I call it from my dashboard.js into my datacontext.js controller; however I would like to actually create a service for this. I would then persist those session vars throughout the lifetime of each user session.
In my initial attempt to create the service I am getting lots of injector errors, for example :
Error: [ng:areq] Argument 'fn' is not a function, got string
I have included it in my index.html:
<script src="app/services/userContext.js"></script>
Here's a dashboard controller snippet where I attempt to inject 'userService' :
(function () {
'use strict';
var controllerId = 'dashboard';
angular.module('app').controller(controllerId, ['$scope', '$routeParams', '$location', 'common', 'datacontext', 'userService', dashboard]);
function dashboard($scope, $routeParams, $location, common, datacontext, userService) {
var getLogFn = common.logger.getLogFn;
var log = getLogFn(controllerId);
var vm = this;
getRzInitParams();
function getRzInitParams() {
log('Initializing Server Connection...');
var rzParams = "";
datacontext.getRzInitParams().then(function (data) {
rzParams = data;
initRz(data);
});
}
function initRz(data) {
var response;
datacontext.initRz().then(function (data) {
response = data[0].split(":")
if (response[1].match(/SUCCESS/g)) {
log('Server init returned ' + response[1].match(/SUCCESS/g));
openUserSession();
}
else {
log('Server init failed !');
}
});
}
}
})();
and here's a snippet from datacontext.js :
(function () {
'use strict';
var serviceId = 'datacontext';
angular.module('app').factory(serviceId, ['$http', 'common', datacontext]);
function datacontext($http, common) {
var $q = common.$q;
var service = {
initRz: initRz,
openUserSession: openUserSession,
getRzInitParams: getRzInitParams
};
return service;
function initRz() {
domain = "localhost:"
port = "49479";
controllerpath = "/api/init";
space = "rz64698";
env = "rz64698";
cl_config = "C:\\Rz\\rz64698\\master\\bin\\cl_config.xml";
var url = "http://" + domain + port + controllerpath + "?space=" + space + "&environment=" + env + "&clConfig=" + cl_config;
var deferred = $q.defer();
deferred.notify("Getting init parameters...");
var retval = [];
$http({
method: 'GET',
encoding: 'JSON',
headers: {
'Access-Control-Allow-Origin': 'true'
},
withCredentials: true,
url: url
}).success(function (data, status, headers, config) {
retval = data;
deferred.resolve(retval);
});
return deferred.promise;
}
function getRzInitParams() {
var deferred = $q.defer();
var retval = [];
$http({
method: 'GET',
encoding: 'JSON',
url: 'breeze/breeze/GetRzEnv'
}).success(function (data, status, headers, config) {
retval = data;
deferred.resolve(retval);
});
return deferred.promise;
}
}
})();
and finally the new 'userService' service I am now creating :
(function () {
'use strict';
var app = angular.module('app');
app.service('userService', '$http', function () {
// define private vars
var _rzEnvParams = [];
var _sessionID = '';
this.initrz = function(domain, port, controllerpath, space, env, clariteconfig) {
domain = "localhost:"
port = "49479";
controllerpath = "/api/init";
space = "rz64698";
env = "rz64698";
cl_config = "C:\\rz\\rz64698\\master\\bin\\clarite_config.xml";
var url = "http://" + domain + port + controllerpath + "?space=" + space + "&environment=" + env + "&clariteConfig=" + cl_config;
var deferred = $q.defer();
deferred.notify("Getting Rage init parameters...");
var retval = [];
$http({
method: 'GET',
encoding: 'JSON',
headers: {
'Access-Control-Allow-Origin': 'true'
},
withCredentials: true,
url: url
}).success(function (data, status, headers, config) {
retval = data;
deferred.resolve(retval);
});
return deferred.promise;
}
this.getrzInitParams = function () {
var deferred = $q.defer();
deferred.notify("Getting Rage init parameters...");
var retval = [];
$http({
method: 'GET',
encoding: 'JSON',
url: 'breeze/Rage/GetrzEnv'
}).success(function (data, status, headers, config) {
retval = data;
deferred.resolve(retval);
});
return deferred.promise;
}
this.openUserSession = function() {
domain = "localhost:"
port = "49479";
controllerpath = "/api/open";
user = "";
pass = "";
var url = "http://" + domain + port + controllerpath + "?userid=" + user + "&pass=" + pass;
var deferred = $q.defer();
deferred.notify("Opening user session...");
var retval = [];
$http({
method: 'GET',
encoding: 'JSON',
headers: {
'Access-Control-Allow-Origin': 'true'
},
withCredentials: true,
url: url
}).success(function (data, status, headers, config) {
retval = data;
deferred.resolve(retval);
});
return deferred.promise;
}
this.closeUserSession = function(domain, port, controllerpath) {
}
});
})();
If you want to inject some service you should use one of this syntaxes
if you need only angular services
app.service('userService', function ($http) {
...
if you need custom services
app.service('myService', ['$http', 'myOtherService', function($http, myOtherService) {
...
}])
app.service('userService', '$http', function () {
should be like
app.service('userService', function ($http) {
hope this will work