I'm sending http post request to REST api, I'm getting status ok response from server but in this script, it always runs 'myError' function. In backend everything is running fine without any error. In error function also response value remains undefined.
var toDoApp = angular.module('toDoApp');
toDoApp.factory('registrationService', function() {
var register = {};
register.registeruser = function(user, $http) {
$http({
method : "POST",
url : 'register',
data : user
}).then(function mySuccess(response) {
console.log("success");
}, function myError(response) {
console.log("error");
});
}
return register;
});
Inject the http service to the factory. Not the registeruser function.
toDoApp.factory('registrationService', function($http) {
Do some needful correction.
var toDoApp = angular.module('toDoApp',[]);
toDoApp.factory('registrationService', function($http) {
var register = {};
register.registeruser = function(user) {
$http({
method : "POST",
url : 'register',
data : user
}).then(function mySuccess(response) {
console.log("success");
}, function myError(response) {
console.log("error");
});
}
return register;
});
Error is showing because you did not inject $http service to to your toDoAppfactory not in your registeruser function . You should inject $http service to your factory. like :
toDoApp.factory('registrationService', function($http)
And your function registeruser should be like
register.registeruser = function(user) {
$http({
method : "POST",
url : 'register',
data : user
}).then(function mySuccess(response) {
console.log("success");
}, function myError(response) {
console.log("error");
});
}
Related
I have a Login page and if user logs in I want to redirect the user to another HTML page where I will list users tasks that I get from server.
The problem is:
Even though the functions I wrote works properly and backend API returns the values I want (I can see the value details on Console) when I use redirect code $window.location.href = '../Kullanici/userPanel.html the page redirects immedietly after login and for some reason I can't use the values returned by functions after redirection. Not only that I can't see the details of the value returned on console log anymore.
And here is my code for it:
Controller:
app.controller('myCtrl', ['$scope', '$http', '$window','$mdToast', 'userTaskList',
function ($scope, $http, $window, $mdToast, userTaskList) {
$scope.siteLogin = function () {
var userName = $scope.panel.loginUserName;
var password = $scope.panel.loginPassword;
var loginMember = { //JSON data from login form
K_ADI: $scope.panel.loginUserName,
PAROLA: $scope.panel.loginPassword
};
$http({
method: 'POST',
url: 'http://localhost:5169/api/Kullanicilar/KullaniciDogrula',
headers: {
'Content-Type': 'application/json'
},
data: loginMember
}).then(function successCallback(response) {
console.log("message sent", response);
$scope.data = response.data.error.data;
if ($scope.data === true) {//if username and password is correct
console.log("User exists");
userTaskList.showActiveTasks(userName)
.then(function (activeTaskResponse) {
var activeTasks = activeTaskResponse;
console.log("Active tasks (controller): ", activeTaskResponse);
userTaskList.showFinishedTasks(userName)
.then(function (finishedTaskResponse) {
var finishedTasks = finishedTaskResponse;
console.log("Finished tasks(controller): ", finishedTaskResponse);
$scope.getMessage();
$window.location.href = '../Kullanici/userPanel.html';
}, function (err) {
console.log(err);
});
}, function (err) {
console.log(err);
});
}
}, function errorCallback(response) {
console.log("Couldn't send", response);
});
}
So what causes this problem and how can I fix it?
Edit: I nested .then parts but it doesnt work properly and gives This value was just evaluated now warning. So I stil can't use data on the redirected HTML page.
I also removed the factory since it makes the code look really messy and its probably not the source of the problem.
I would have nested the your two functions inside the first promise, then redirect once all of them are done. Something like
app.controller('myCtrl', ['$scope', '$http', '$window','$mdToast', 'userTaskList',
function ($scope, $http, $window, $mdToast, userTaskList) {
$scope.siteLogin = function () {
var userName = $scope.panel.loginUserName;
var password = $scope.panel.loginPassword;
var loginMember = { //JSON data from login form
K_ADI: $scope.panel.loginUserName,
PAROLA: $scope.panel.loginPassword
};
$http({
method: 'POST',
url: 'http://localhost:5169/api/Kullanicilar/KullaniciDogrula',
headers: {
'Content-Type': 'application/json'
},
data: loginMember
}).then(function successCallback(response) {
console.log("message sent", response);
$scope.data = response.data.error.data;
if ($scope.data === true) {//if username and password is correct
console.log("User exists");
userTaskList.showActiveTasks(userName)
.then(function (res) {
var activeTasks = res;
console.log("Active tasks (controller): ", res);
userTaskList.showFinishedTasks(userName)
.then(function (res) {
var finishedTasks = res;
console.log("Finished tasks(controller): ", res);
$scope.getMessage();
$window.location.href = '../Kullanici/userPanel.html';
}, function (err) {
console.log(err);
});
}, function (err) {
console.log(err);
});
} else { //if username or password is wrong
$mdToast.show(
$mdToast.simple()
.textContent('Username or Password is wrong')
.position('right')
.hideDelay(3000)
);
}
}, function errorCallback(response) {
console.log("Couldn't send", response);
});
}
}
]);
Oh I injected ngRoute to my AngularJS module but haven't use it yet.
Using $window.location.href kills the app and loads the other page, losing $rootScope, $scope, and all service data.
Re-factor your code to use a router and store the data in a service:
$routeProvider
.when('/userPanel' , {
templateUrl: 'partials/userPanel.html',
controller: panelController
})
panelService.set(data);
$location.path("/userPanel.html");
OR use localStorage to store the data:
localStorage.setItem('panelData', JSON.stringify(data));
$window.location.href = '../Kullanici/userPanel.html';
Data stored in a service will survive route changes (which destroy $scope). Data stored in localStorage will survive page changes (which destroy apps).
The code can be simplified
This will solve the problem of having the page wait for the data before changing the route.
Since the getMessages function makes an HTTP request it needs to be modified to return a promise:
$scope.getMessages = getMessages;
function getMessages() {
return $http({
method: 'GET',
url: 'http://localhost:5169/api/chat/chatCek'
}).then(function successCallback(res) {
console.log("Mesajlar", res);
$scope.messages = res.data.error.data;
return res.data.error.data;
}, function errorCallback(res) {
console.log("Hata", res);
throw res;
});
}
Then to delay the changing of the route until the getMessages data returns from the server, chain from the getMessages promise:
$http({
method: 'POST',
url: 'http://localhost:5169/api/Kullanicilar/KullaniciDogrula',
data: loginMember
}).
then(function successCallback(response) {
console.log("message sent", response);
$scope.data = response.data.error.data;
if ($scope.data !== true) { throw "user error" };
//username and password is correct
console.log("User exists");
return userTaskList.showActiveTasks(userName);
}).
then(function (activeTaskResponse) {
var activeTasks = activeTaskResponse;
console.log("Active tasks (controller): ", activeTaskResponse);
return userTaskList.showFinishedTasks(userName)
}).
then(function (finishedTaskResponse) {
var finishedTasks = finishedTaskResponse;
console.log("Finished tasks(controller): ", finishedTaskResponse);
//CHAIN from getMessages promise
return $scope.getMessages();
}).
then(function(data) {
console.log(data);
//SAVE data before changing route
panelService.set(data);
$location.path( "/userPanel" );
//OR STORE data before changing app
//localStorage.setItem('panelData', JSON.stringify(data));
//$window.location.href = '../Kullanici/userPanel.html';
}).
catch(function (response) {
console.log("Couldn't send", response);
throw response;
});
I want to send custom POST parameter (CSRF token) on every $http post request on AngularJS. I tried with an interceptor, it works but is sending parameter as GET, and I need to send as POST.
Basically I need something like $.ajaxSetup() on jQuery.
$http request:
App.controller('LoginController', function ($scope, $window, $http)
{
$scope.email = undefined;
$scope.password = undefined;
$scope.login = function() {
var request = $http({
method: "POST",
url: gurl + 'user/login',
// headers: {'Content-Type' : 'application/x-www-form-urlencoded', 'X-Requested-With' :'XMLHttpRequest'},
data: $.param({email: $scope.email, password: $scope.password})
});
request.success(function(data) {
if(angular.equals(data.status, 'success')) {
$window.location.href = gurl + 'dashboard';
}
else {
noty('error', data.msg);
}
});
}
});
Interceptor
App.factory('csrfInterceptor', function($q, $location, $injector)
{
return {
// optional method
'request': function(config) {
// do something on success
config.param = config.param || {};
config.param.csrf_token = $("input:hidden[name='csrf_token']").val();
return config;
}
};
});
I have a service that returns a promise.
function GetSuggestedPeersService($http, SITE_CONFIG) {
var getSuggestedPeersService = this;
var data;
getSuggestedPeersService.getSuggestedPeersList = function() {
var baseUrl = SITE_CONFIG.baseUrl + "fetchSuggestedPeers";
var response = $http({
method : 'POST',
url : baseUrl,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
},
data : data
});
return response;
}
getSuggestedPeersService.setSuggestedPeers = function(suggestedPeers) {
getSuggestedPeersService.suggestedPeers = suggestedPeers;
}
getSuggestedPeersService.getSuggestedPeers = function() {
return getSuggestedPeersService.suggestedPeers;
}
}
Now I use the following in the Controller to resolve the promise:
//gets the suggested peers
var promiseSuggestedPeers = GetSuggestedPeersService.getSuggestedPeersList();
promiseSuggestedPeers.then(function (response) {
peerHealthController.GetSuggPeersShow = response.data;
GetSuggestedPeersService.setSuggestedPeers(peerHealthController.GetSuggPeersShow);
return peerHealthController.GetSuggPeersShow;
})
.catch(function (error) {
console.log("Something went terribly wrong Suggested Peers.");
});
Now my question is call this service multiple times and need to update this on other service calls as well.
What is the best way to write the controller part so as not to repeat the resolve promise every time I call the service?
It's been long time.
But I just wanted to answer this question.
The best way to design this would be to use a factory. So this will become a reusable service.
An example code can be the following:
var httpMethods = peerHealthApp.factory('HttpService',HttpService);
httpMethods.$inject = ['$http', 'SITE_CONFIG'];
function HttpService($http, SITE_CONFIG){
console.log("SITE_CONFIG from Peer Service: " + SITE_CONFIG);
var factory = {
httpGet : function(relativePath,data){
var baseUrl = SITE_CONFIG.baseUrl + relativePath;
var response = $http({
method : 'GET',
url : baseUrl,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
},
data : data
});
return response;
},
httpPost : function(relativePath, data){
var baseUrl = SITE_CONFIG.baseUrl + relativePath;
var response = $http({
method : 'POST',
url : baseUrl,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
},
data : data
});
return response;
}
};
return factory;
}
And the above can be used again and again like the following:
var data=$.param({
"url":moderatedArticleLink
});
var promiseURLMetaData = HttpService.httpPost("parseUrlMetadata", data);
promiseURLMetaData.then(function (response) {
var urlMetaData = response.data;
return urlMetaData;
})
.catch(function (error) {
console.log("Something went terribly wrong while trying to get URL Meta Data.");
});
What is the best way to write the controller part so as not to repeat the resolve promise every time I call the service?
Instead of saving the data in a service, I recommend saving the promise:
if ( !Service.get() ) {
var promise = Service.fetch();
Service.set(promise);
});
Service.get().then(function (response) {
$scope.data = response.data;
}).catch( function(errorResponse) {
console.log(errorResponse.status);
throw errorResponse;
});
By checking for the promise and only fetching if necessary, multiple controllers can share the data without caring about the order of controller instantiation. This avoids race conditions and multiple XHRs to the same resource.
Why is it that when I try to retrieve data with this simple API call I get an error that says http://127.0.0.1:8080/%7B%7Buser.avatar%7D%7D <- ? But if I move my promise into my controller it works. I thought that you can make your promises in your service and it'll work fine?
This is my controller.js file
angular.module('userProfiles').controller('MainController', function($scope, mainService) {
$scope.getUsers = function() {
mainService.getUsers();
}
$scope.getUsers();
});
This is my services.js file
angular.module('userProfiles').service('mainService', function($http) {
var baseUrl = 'http://reqres.in/api/users?page=1';
this.getUsers = function() {
return $http({
method: 'GET',
url: baseUrl
}).then(function(response) {
this.users = response.data.data;
});
}
});
You aren't assigning the response.data.data to anything usable outside that callback. Try it like this instead, returning a promise that resolves with the users data...
this.getUsers = function() {
return $http.get('http://reqres.in/api/users', {
params: {page: 1}
}).then(function(res) {
return res.data.data;
});
};
and in your controller
$scope.getUsers = function() {
mainService.getUsers().then(function(users) {
$scope.users = users;
});
};
I have an angularjs factory to get data via $http.get():
'use strict';
app.factory('apiService', ['$http', function ($http) {
var apiService = {};
apiService.urlBase = 'http://localhost:1337/api/';
apiService.get = function (urlExtension) {
$http({
method: 'GET',
url: apiService.urlBase + urlExtension
}).then(function successCallback(response) {
return response.data;
}, function errorCallback(response) {
console.log(response);
});
}
return apiService;
}]);
The problem is, that it always returns undefined when i call the method apiService.get(); in a Controller. When I log the response data in the factory, it display the right data. The apiService.urlBase variable is always filled in my controller.
Do you guys have any suggestions or am I doing something wrong? Maybe it's a syntax error.
You are not returning the promise that is returned by $http. Add return before $http
Okay I solved the problem. I just passed a callback function via parameter for my get() function.
'use strict';
app.factory('apiService', ['$http', function ($http) {
var apiService = {};
apiService.urlBase = 'http://localhost:1337/api/';
apiService.get = function (urlExtension, callback) {
var data = {};
$http({
method: 'GET',
url: apiService.urlBase + urlExtension
}).then(function successCallback(response) {
data = response.data;
callback(data);
}, function errorCallback(response) {
console.log(response);
});
return data;
}
return apiService;
}]);