I have a weird problem.. when I am loading my details page, the error part gets executed first in the controller.
Though the service myService gets executed and it does return value, in the controller error is executed and I am not getting my message details.
I have put an alert in service before and jsonObj is valid.
controller:
url = 'http://' + add + ':8080/user/site.cgi';
data = {
ACTION : "list",
STATS : "no"
};
myService.getdata(url, data)
.then(function(data, status, headers, config) {
$timeout(function(){
if (data.body.response.status == "OK") {
if (data.body.response.msg.id) {
service2.seturl(data.body.response.msg.id, username, add);
messg.push(data.body.response.msg);
} else
angular.forEach(data.body.response.msg, function(value, key) {
service2.seturl(value.id, username, add);
messg.push(value);
})
$rootScope.messg = messg;
} else {
errorMessage = data.body.response.errmsg;
alert(errorMessage);
}
}, 5000);
}, function(error, status, headers, config) {
alert("Check network connection.."); //Coming here without fulfilling promise.
});
}
services:
.service('myService', function($http, $q, $httpParamSerializerJQLike) {
return {
getdata: function(url, data) {
var postData = data;
return $http({
method : 'POST',
url : url,
data : $httpParamSerializerJQLike(postData)
}).then(function(response, status, headers, config) {
var x2js = new X2JS();
var jsonObj = x2js.xml_str2json(response.data);
if (typeof jsonObj === 'object') {
alert(jsonObj); //I am getting this alert just fine.
return jsonObj; //It does return the object.
} else {
return $q.reject(jsonObj);
}
}, function(response, status, headers, config) {
return $q.reject(response.data);
});
}
}
})
.factory('service2', function() {
var urls = [{ }];
return {
all: function() {
return urls;
},
geturl: function(id) {
for (var i = 0; i < urls.length; i++) {
if (urls[i].id === parseInt(id)) {
return urls[i];
}
}
return null;
},
seturl: function(id, admin, add) {
for (var i = 0; i < urls.length; i++) {
if (urls[i].id === parseInt(id)) {
return null;
}
}
var idInt = parseInt(id);
var createurl = 'http://' + add + ':8080/user/det.cgi';
var postData = {
ACTION : “add”,
LOGIN : admin
};
var url = {
id: idInt,
url: createurl,
data: postData
}
urls.push(url);
return null;
}
};
})
Try this , return a deferred promise
.service('myService', function($http, $q, $httpParamSerializerJQLike) {
return {
getdata: function(url, data) {
var deferred = $q.defer();
var postData = data;
$http({
method : 'POST',
url : url,
data : $httpParamSerializerJQLike(postData)
}).then(function(response, status, headers, config) {
var x2js = new X2JS();
var jsonObj = x2js.xml_str2json(response.data);
if (typeof jsonObj === 'object') {
alert(jsonObj);
deferred.resolve(jsonObj);
} else {
deferred.reject(jsonObj);
}
}, function(response, status, headers, config) {
deferred.reject(response.data);
});
return deferred.promise;
}
}
})
Related
i'm developing an app that received from a server a JSON array and divided data in a specific way, i've a portion of code that works if i use it alone but if i tried to insert it in an application it doesn't work.
This is my code:
ionicApp.controller('DefaultController', DefaultController)
.factory('dataService', dataService);
DefaultController.$inject = ['dataService', '$http'];
function DefaultController(dataService, $http) {
var vm = this;
console.log("Dentro ctrl");
getEvents();
function getEvents() {
console.log("Dentro getEvents");
return dataService.getEvents()
.then(function (data) {
console.log("data: " + data);
vm.data = data;
console.log("vm.data: " + vm.data);
return vm.data;
});
}
vm.submit = function (){
console.log("funzione");
console.log(vm.form);
var data = vm.form; // IMPORTANT
//console.clear();
var link = 'http://localhost/<path>/api/apiDoFix.php';
var mail = window.localStorage.getItem("mail");
var scelta = window.localStorage.getItem("scelta");
console.log(data);
console.log ("EMAIL" + mail);
console.log ("SCELTA" + scelta);
$http.post(link, {giorno: data.giorno, ora: data.ora, mail: mail, scelta: scelta})
.then(function (res){
console.log("Dentro http.post");
var response = res.data;
if (response != 'F'){
console.log("Dentro if");
console.log(response);
//window.location.href ="/#/main";
} else {
console.log("Dentro else");
}
});
};
}
dataService.$inject = ['$http'];
function dataService($http) {
console.log("qua");
var service = {
getEvents: getEvents
};
return service;
function getEvents() {
console.log("qua2");
var config = {
transformResponse: function (data, headers) {
var result = {
events: [],
schedules: []
};
var events = JSON.parse(data);
var dates = [];
console.log("qua3");
for (var i = 0; i < events.length; i++) {
if (dates.indexOf(events[i].day) === -1) {
var date = events[i].day;
dates.push(date);
result.events.push({
date: date
});
}
result.schedules.push({
date: events[i].day,
time: events[i].time
});
}
console.log("result: " + result);
return result;
}
};
return $http.get('http://localhost/ShuttleFIX/api/apiTimes.php', config)
.then(getEventsCompleted)
.catch(getEventsFailed);
function getEventsCompleted(response) {
console.log("response " + response.data);
return response.data;
}
function getEventsFailed(error) {
console.error(error);
}
}
}
is it possible to rewrite this code in a controller function without using factory?
Thank's
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;
});
In my flow say i am using an access token for getting my data. When my access token expires i get a 401 error i am using the refresh token to get a new access token.
Note : My access token and refresh token is stored in a cookie and i am updating the same after a 401 error.
My question how do i retry the same operation which i was in the middle of?
My Code (services.js):
var refresh_token = "na";
function get_api_data(url, api_token) {
var returnData = handleApiData(url, api_token, "GET");
return returnData;
}
function post_api_data(url, api_token, post_data) {
var returnData = handleApiData(url, api_token, "PUT", post_data);
return returnData;
}
function handleApiData(url, access_token, type, post_data) {
return $.ajax({
url: url,
type: type,
data: post_data,
error: failHandler,
contentType: "application/json",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Bearer " + access_token);
}
})
}
function handleData(data, textStatus, jqXHR) {
return data;
}
function failHandler(jqXHR, textStatus, errorThrown) {
switch (jqXHR.status) {
case 401:
var api = get_api_token();
checkApiToken(api.refresh_token);
break;
default:
alert(errorThrown);
}
}
function checkApiToken(refresh_token) {
if (refresh_token != "na") {
$.post("/Account/Refresh/?refresh_token=" + refresh_token);
//location.reload();
}
}
My Code (notification.js):
$(function () {
var api = get_api_token();
if (api != null)
get_notification_data(api.access_token);
});
function get_notification_data(api_token) {
var notifications = get_api_data(urls.notifications.list, api_token);
if (notifications != undefined)
notifications.success(function (data) {
items = data.records;
_.each(items, function (item) {
item.Status = ko.observable(item.status);
item.onClick = function () {
if (item.Status() === 'UNREAD') {
var post_data = { id: item.id };
post_api_data(urls.notifications.list, api_token, post_data).success(function (response, textStatus) {
if (response.success)
item.Status('READ');
$(location).attr("href", item.action_link);
});
}
else {
$(location).attr("href", item.action_link);
}
}
});
var model = {
items: ko.observableArray(items),
onCancel: function (item) {
}
}
ko.applyBindings(model, $("#notificationBar")[0]);
})
}
Edit: My AccountController code that sets the new API cookie:
[HttpPost]
public ActionResult Refresh(string refresh_token)
{
string token_string = string.Empty;
try
{
token_string = OAuthHelper.getTokenViaRefreshTokenFromAPIServer(refresh_token);
if(token_string != null)
Response.Cookies[Constants.Cookies.API].Value = token_string;
}
catch (Exception ex)
{
Log.Info(string.Format("AccountController.cs -Refresh Token Error ", ex.Message));
}
return RedirectToAction("Index","Home");
}
I am leaning Angular my first application is a photo sharing tool. I added the code for the upload function and broke it. I thought I was defining the albumProvider in my controller, but apperently I have failed to do so. The error is Error: [$injector:unpr] Unknown provider. I am stuck and could us a hand on what I need to fix.
albumService.js
(function () {
function albumProvider($http,$fileUploader) {
this.getUploader = function (album_name, scope) {
return $fileUploader.create({
scope: scope,
method: "PUT",
url: "/v1/albums/" + album_name + "/photos.json"
});
};
this.getAlbums = function (callback) {
$http.get("/v1/albums.json")
.success(function (data, status, headers, conf) {
callback(null, data);
})
.error(function (data, status, headers, conf) {
callback(data);
});
};
this.getPhotosForAlbum = function (name, callback) {
$http.get("/v1/albums/" + name + "/photos.json")
.success(function (data, status, headers, conf) {
callback(null, data);
})
.error(function (data, status, headers, conf) {
callback(data);
});
};
this.addAlbum = function (album_data, callback) {
if (!album_data.name) return callback({ code: "missing_name" });
if (!album_data.title) return callback({ code: "missing_title" });
if (!album_data.description) return callback({ code: "missing_description" });
if (!album_data.date) return callback({ code: "missing_date" });
if (!is_valid_date(album_data.date)) return callback({ code: "bad_date" });
$http.put("/v1/albums.json", album_data)
.success(function (data, status, headers, conf) {
callback(null, data);
})
.error(function (data, status, headers, conf) {
callback(data);
});
};
}
photoApp.service("albumProvider", albumProvider);
function is_valid_date(the_date) {
if (the_date.match(/^[0-9]{2,4}[\-\/\. ,][0-9]{1,2}[\-\/\. ,][0-9]{1,2}$/)) {
var d = new Date(the_date);
return !isNaN(d.getTime());
} else {
return false;
}
}
})();
albumUploadController.js
(function () {
function AlbumUploadController($scope, $routeParams, albumProvider) {//Dependency Inject albumProvider
$scope.album_name = $routeParams.album_name;
$scope.page_load_error = '';
$scope.description = {};
albumProvider.getPhotosForAlbum($scope.album_name, function (err, photos) {
if (err) {
if (err.error == "not_found")
$scope.page_load_error = "No such album. Are you calling this right?";
else
$scope.page_load_error = "Unexpected error loading page: " + err.code + " " + err.message;
} else {
$scope.photos = photos;
$scope.uploader = albumProvider.getUploader($scope.album_name, $scope);
$scope.uploader.bind("completeall", function (event, items) {
$scope.done_uploading = true;
});
}
});
$scope.uploader.bind('beforeupload', function (event, item) {
var fn = _fix_filename(item.file.name);
var d = item.file.lastModifiedDate;
var dstr = d.getFullYear() + "/" + d.getMonth() + "/" + d.getDate();
item.formData = [{
filename: fn,
date: dstr,
description: $scope.descriptions[item.file.name]
}];
});
}
photoApp.controller("AlbumUploadController", AlbumUploadController);
function _fix_filename(fn) {
if (!fn || fn.length == 0) return "unknown";
var r = new RegExp("^[a-zA-Z0-9\\-_,]+$");
var out = "";
for (var i = 0; i < fn.length; i++) {
if (r.exec(fn[i]) != null)
out += fn[i];
}
if (!out) out = "unknown_" + (new Date()).getTime();
}
})();
app.js
var photoApp = angular.module('photoSharingApp', ['ngRoute']);
photoApp.config(function ($routeProvider) {
$routeProvider
.when("/albums", {
controller: "AlbumListController",
templateUrl: "/app/partial/albumPartial.html"
})
.when("/album/:album_name", {
controller: "AlbumViewController",
templateUrl: "/app/partial/albumViewPartial.html"
})
.when("/album/:album_name/upload", {
controller: "AlbumUploadController",
templateUrl: "/app/partial/albumUploadPartial.html"
})
.when("/album/photos/:album_name/:photo_filename", {
controller: "PhotoViewController",
templateUrl: "/app/partial/photoViewPartial.html"
})
.when("/", {
redirectTo: "/albums"
})
.when("/404_page", {
controller: "Controller404",
templateUrl: "/app/partial/404Partial.html"
})
.otherwise({
redirectTo: "/404_page"
});
});
you need to set up the file uploader in your app configuration like:
var photoApp = angular.module('photoSharingApp', ['ngRoute','angularFileUpload']);
then as far i know you may change your fileuploader definition for:
return new FileUploader({
scope: scope,
method: "PUT",
url: "/v1/albums/" + album_name + "/photos.json"
});
I'm not sure about passing the scope to the service, but you can try that out, also don't forget to update your dependency from $fileUploader to FileUploader
here is the code:
authServ.getUser() returns {} (an empty object, which corresponds to the declaration of this var), from everywhere, even after the revision that I have made to the return syntax according to this [question][1].
Can anyone please advise what is the issue?, I don't see a reason why it shouldn't work
app.factory('authService', function($http){
var authServ = {};
var currentUser = {};
authServ.authUser = function(){
return $http.head('/users/me', {withCredentials: true});
},
authServ.getUser = function(){
return currentUser;
},
authServ.setCompany = function(companyId){
currentUser.company = companyId;
}
authServ.loadCurrentUser = function(){
$http.get('/users/me', {withCredentials: true}).
success(function(data, status, headers, config){
console.log(data);
currentUser.company = currentUser.company ? currentUser.company : data.main_company;
currentUser.companies = [];
for(var i in data.roles){
currentUser.companies.push(data.roles[i]['company_name']);
if(data.roles[i]['company'] == currentUser.company)
currentUser.role = data.roles[i]['role_type'];
}
console.log(currentUser);
}).
error(function(data, status, headers, config){
currentUser.role = 'guest';
currentUser.company = 1;
});
}
return authServ;
});
WORKING CODE:
run(function($rootScope, $location, $http, authService){
$rootScope.$on("$routeChangeError", function(event, current, previous, rejection){
if(rejection.status == 401)
$location.path('/login');
})
authService.loadCurrentUser().then(function(){
console.log(authService.getUser());
});
});
app.factory('authService', function ($http) {
authServ = {};
that = this;
that.currentUser = {};
authServ.authUser = function () {
return $http.head('/users/me', {
withCredentials: true
});
},
authServ.getUser = function () {
return that.currentUser;
},
authServ.setCompany = function (companyId) {
that.currentUser.company = companyId;
},
authServ.loadCurrentUser = function () {
return $http.get('/users/me', {
withCredentials: true
}).
success(function (data, status, headers, config) {
console.log(data);
that.currentUser.company = that.currentUser.company ? that.currentUser.company : data.main_company;
that.currentUser.companies = [];
for (var i in data.roles) {
that.currentUser.companies.push(data.roles[i]['company_name']);
if (data.roles[i]['company'] == that.currentUser.company) that.currentUser.role = data.roles[i]['role_type'];
}
console.log(that.currentUser);
}).
error(function (data, status, headers, config) {
that.currentUser.role = 'guest';
that.currentUser.company = 1;
});
}
return authServ;
});
Fiddle:
http://jsfiddle.net/V9Ex6/1/
Closure issue. Try
app.factory('authService', function($http){
var authServ = {};
that = this; //that captures the current closure
this.currentUser = {};
authServ.getUser = function(){
return that.currentUser;
},
And change loadCurrentUser to access to the variable using that.currentUser.
Edit:
authService.loadCurrentUser();
console.log(authService.getUser());
The user is not guaranteed to be printed out since loadCurrentUser loads the user asynchronously. You should change loadCurrentUser to take a callback function in order to get the user value.
Hope it helps.
Try this, mind you I haven't tested it :)
app.factory('authService', function($http){
return {
authUser: function(){
return $http.head('/users/me', {withCredentials: true});
},
getUser: function(){
return currentUser;
},
setCompany: function(companyId){
currentUser.company = companyId;
},
loadCurrentUser: function(){
$http.get('/users/me', {withCredentials: true}).
success(function(data, status, headers, config){
console.log(data);
currentUser.company = currentUser.company ? currentUser.company : data.main_company;
currentUser.companies = [];
for(var i in data.roles){
currentUser.companies.push(data.roles[i]['company_name']);
if(data.roles[i]['company'] == currentUser.company)
currentUser.role = data.roles[i]['role_type'];
}
console.log(currentUser);
}).
error(function(data, status, headers, config){
currentUser.role = 'guest';
currentUser.company = 1;
});
}
}
});