How to post a json to my app ionic => symfony fosrestbundle - angularjs

I'm pretty new in angularJs, in my ionic
app I try to post
a json to my app symfony fosrestbundle my app is correctly config.
but when I send my post the console
shows me this error message:
XMLHttpRequest cannot load
http://127.0.01/gl/web/api/articles/5/comments . response for preflight has invalide status 405
I'm going crazy! does anyone have any
idea?!thanks a lot for the attention

how are you doing it?
First you need to bind the function to your html like this:
<button class="button button-energized" ng-click="login()">Login</button>
It's recomendded to use a service to do http calls, but you need to inject it (LoginService) in your controller:
.controller('LoginCtrl', function($scope, LoginService) {
$scope.login = function() {
LoginService.loginUser($scope.data.user, $scope.data.password)
.then(function (data) {
//grant access to the app
});
};
});
And in your service:
.factory('LoginService', function($http) {
return {
loginUser: function(user, password) {
return $http.post('http://mydomain/login', {
user: user,
password: password
});
}
};

Related

How to: AngularJS http GET request to Laravel CRUD resource controller

I have been trying to get a response from my laravel resource controller through a http GET request from angularJS. Please let me know what i'm doing wrong. My console.log() does not show anything.
Web.php file has the following route
Route::resource('comments', 'CommentsController');
I have a laravel resource(CRUD) controller named CommentsController which has the function.
public function show(Comment $comment) {
//show comement
$articleComments = DB::table('comments')->where('id', $comment->articleID);
if (!$articleComments->isEmpty()) {
//return Json as response
return response()->json($articleComments);
} else {
return response()->json(['status' => 'Not Found!']);
}
}
This is what my laravel route list looks like for comments
Laravel route:list for comments controller
I want to use AngularJS http GET request to retrieve comments for an article. This is my AngularJS code.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$scope.loadComments = function(id){
$http.get("comments",{
params: {
'articleID': id
}})
.then(function(response) {
//First function handles success
console.log(response.data)
}, function(response) {
//Second function handles error
console.log(response.data)
});
}
});
I have included the CSRF protection tag as well
<meta name="csrf-token" content="{{ csrf_token() }}">
My html button that initiated the loadComments
<button type="button" id="getArticleId" class="btn btn-default" aria-label="comment button" ng-click="loadComments({{$key->id}})">
My response looks like
Chrome network analysis header output

angularjs http interceptor to show error on loaded location path

I have an application for which I created an interceptor to handle token expirations after 15 minute inactivity, it successfully redirects to the login page after a token has expired, but Im not able to show the error after redirecting to the login page.
My question is, how can I show the user the token expired error on the login page, after the interceptor has redirected the app to that page.
Heres my redirector:
app
.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push(function($q, $location, LoopBackAuth) {
return {
responseError: function(rejection) {
if (rejection.status == 401) {
//Now clearing the loopback values from client browser for safe logout...
LoopBackAuth.clearUser();
LoopBackAuth.clearStorage();
$location.path("/login");
}
return $q.reject(rejection);
}
};
})
}])
.config(function(LoopBackResourceProvider) {    
LoopBackResourceProvider.setAuthHeader('X-Access-Token');
})
Finally and thanks to #forrestmid to point me in the right direction this is what I ended up doing.
on the http interceptor just added:
$location.path("/login").search({error: 'invalid_token'});
and then on the controller just had to do:
var queryString = $location.search();
$scope.errors = {};
if (queryString && queryString.error) {
$scope.errors = {
'invalid_token': {
code: 'invalid_token'
}
}
}
now on the template I already have logic to handle the error object so now it works fine :)
Referencing this post in regards to injecting the $state service into an HTTP interceptor:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push(function($q, $injector, LoopBackAuth) {
return {
responseError: function(rejection) {
if (rejection.status == 401) {
//Now clearing the loopback values from client browser for safe logout...
LoopBackAuth.clearUser();
LoopBackAuth.clearStorage();
$injector.get('$state').go('app.login', {error: 'Token expired.'});
}
return $q.reject(rejection);
}
};
})
}]);
Assuming that you're using ui.router:
app.config(function($stateProvider){
$stateProvider
.state("app",{abstract: true})
.state("app.login", {
url: "/login",
params: {error: ""}
});
});
By default there will be no error when transitioning to the app.login state, but when there is a param error set to whatever, it can display the error. This will be in the $stateParams.error variable on your login page.
Let me know if I botched any of that code since I didn't test it. The line I think you want is the $injector line.

How can I redirect a user to the login page using angularjs and laravel

I am working on a project using laravel and angularjs. I am using only Laravel to authenticate the users and when their logged in, then angularjs ui veiw will handle the navigation. when doing this I realized a problem, when the session has expire the user should be redirected to the logged in page based on the auth filter that is set on the route. Additionally when I checked the browser dev tool network tab, I see that the sign in page is send as a response. I am wondering how can I make my project redirect the user to the logged in page when the session has expire. how can I solve this problem and Thanks in advance for the assistance.
You can do that with $httpInterceptor, here is demo code:
var myApp = angular.module("MyApp", []);
myApp.config(function ($httpProvider, $provide) {
$provide.factory('myHttpInterceptor', function ($q, $location) {
return {
'response': function (response) {
//you can handle you sucess response here.
return response;
},
'responseError': function (rejection) {
console.log(rejection);
//if(rejection.data.xxx==="xxx")
if(rejection.status === 408){//session expired code
alert('logout!');
// clear your local data here...
$location.url("/login")
}
return $q.reject(rejection);
}
};
});
$httpProvider.interceptors.push('myHttpInterceptor');
});
myApp.controller("MainController", function ($scope, $http) {
$scope.response = {};
$scope.triggerGet = function () {
$http.get("/my/json").success(function (data) {
$scope.response = data;
});
};
});
When your server side response is session expired, you can handle the response.status or you can handle the other data with response.data.
Here is $httpInterceptor document.(In the middle of the page)
To redirect the user client-side in JavaScript use location. https://developer.mozilla.org/en-US/docs/Web/API/Location
For this case I think you want to look at location.assign() specifically.

Is it possible AngularJS acess request and session scope of my application?

When I make a request and set on the request and session scope (server side) some attributes. I would like to know if is it possible to get with AngularJS these attributes at my server side.
If you are looking for any "session integration" for authentication purposes, take a look at Spring Session in conjunction with Spring Security. I wrote a little sample application that illustrates how to integrate AngularJS with Spring Security by exposing the session id as an HTTP header (x-auth-token). The corresponding blog post is here.
Yes it is possible, typically one can do as charlietfl said very easily when performing an asynchronous login. Just return some JSON containing upon a successful login.
I store the returned JSON in a ".value" service:
var app = angular.module('app', [])
.value('appData', {})
.factory('authService', ['$http', '$q', 'appData',
function authService($http, $q, appData) {
var setAppData = function(data) {
angular.copy(data, appData);
};
return {
login: function() {
var deferred = $q.defer();
$http.post('/auth', data)
.success(function(response){
deferred.resolve(response);
setAppData(response);
})
.error(function(reason){
deferred.reject(reason);
});
return deferred.promise;
},
logout: function() {
//...http call to logout
setAppData({});
}
};
}
])
;

How to build a simple $http post test script using angular js

I'm just beginning to understand Angularjs and planning to build an app. I'm really a PHP programmer and have little background in javascript. Angularjs was introduced to me by a friend. I was warned that I have to also learn its Jasmine/karma testing before the functionality of the app gets bigger. So here goes, for now I have a $http post which submits an email and a password which if success return a token. Basically if success will redirect the user to the user/profile page
Controller code:
function MainCtrl($scope, $location, Api, localStorageService, Security) {
$scope.loginUser = function () {
Api.authenticatePlayer({
email : $scope.main.email,
password : $scope.main.password
}).then(function (result){
//success
$location.path('/user/profile');
}, function(result) {
//error also this will catch error 400, 401, and 500
console.log(result.data);
});
};
}
And here is my testscript:
beforeEach(function() {
module('myApp.services'),
module("myApp.controllers")
});
beforeEach(inject(function($controller, $rootScope, $location, Api, localStorageService, $httpBackend, Security) {
this.$location = $location;
this.$httpBackend = $httpBackend;
this.scope = $rootScope.$new();
this.redirect = spyOn($location, 'path');
$controller("MainCtrl", {
$scope : this.scope,
$location : $location,
localStorageService : localStorageService,
Security : Security
});
}));
describe("successfully logging in", function () {
it("should redirect you to /user/profile", function() {
//arrange
var postData = {
email : this.scope.main.email,
password : this.scope.main.password
}
this.$httpBackend.expectPOST('login', postData).respond(200);
//act
this.scope.loginUser();
this.$httpBackend.flush();
//assert
expect(this.redirect).toHaveBeenCalledWith('/user/profile');
});
});
Here is my service.js code:
return {
/**
* Authenticate player
* #param object postData Email and password of the user
* #return object
*/
authenticatePlayer: function(postData) {
return $http({
method : 'POST',
url : api + 'auth/player',
data : postData,
headers : {'Content-Type' : 'application/json'}
});
}
}
The testscript failed :(.
Here is the error:
Chrome 24.0 (Linux) controller: MainCtrl successfully logging in should redirect you to /user/profile FAILED
Error: Unexpected request: POST http://domain.com/auth/player
Expected POST login
Can anyone please help. So sorry for the trouble though.
So, this is because Api.authenticatePlayer is calling to a different path than what you are expecting.
Your test should have this instead:
this.$httpBackend.expectPOST('http://domain.com/auth/player', postData).respond(200);
Basically, in your test, $httpBackend is a mock of the code that would call your API. You get to say "When my code calls this URL, respond with _". In this code, you are saying that you expect the post to happen and to return an empty response of 200. You could replace "200" with the json payload that you want to pretend that the server responded with.

Resources