Laravel 4 + Angular authentication routing - angularjs

I have an application built using Laravel 4 and AngularJS. Everything is working pretty well except for logout. If I access the route directly (/user/logout), the user is successfully logged out and redirected back to the /login page. However, when I try to link to the laravel logout route in the views, it does not work. I think angular is blocking. I've tried to play around with a few things, but always, the url appears for a split second in the address bar and nothing happens.
From app/views/albums/index.blade.php
<ul>
#if(Auth::check())
<li>My Account</li>
<li>Logout</li>
#endif
</ul>
public/js/app.js
(function() {
var app = angular.module('chp', ['ngRoute', 'projectControllers']);
app.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
$routeProvider.
when('/albums', {
templateUrl: '/partials/directory.html',
controller: 'ProjectsCtrl'
}).
when('/albums/:slug', {
templateUrl: '/partials/album.html',
controller: 'ProjectDetailCtrl'
}).
otherwise({
redirectTo: '/login'
});
$locationProvider.html5Mode(true);
}]);
var projectControllers = angular.module('projectControllers', []);
projectControllers.controller('ProjectsCtrl', ['$scope', '$http',
function ($scope, $http) {
$http.get('/get_albums', {cache: true}).success(function(albums) {
$scope.projects = albums;
$scope.filters = { };
});
}]);
projectControllers.controller('ProjectDetailCtrl', ['$scope', '$http', '$routeParams', '$sce',
function($scope, $http, $routeParams, $sce) {
$http.get('/get_albums', {cache: true}).success(function(albums) {
$scope.projects = albums;
$scope.filters = { };
for(var i = 0; i < $scope.projects.length; i++) {
if($scope.projects[i].slug === $routeParams.slug) {
$scope.album = $scope.projects[i];
$scope.albumIdx = i;
break;
}
}
$scope.project = albums[$scope.albumIdx];
$scope.showVideo = function(id) {
var videoCode = $(this)[0].song.video;
var listItem = $('li[data-songid="'+id+'"]');
$('li.video').remove();
$(listItem).after('<li class="video"><img src="/img/progress.gif" alt="Loading..."><div class="flex-video">'+videoCode+'</div></li>');
$('li.video').slideDown();
setTimeout(function() {
$('li.video img').hide();
$('li.video .flex-video').fadeIn();
}, 500);
}
$scope.addLyrics = function(id) {
$('#lyricsModal .track-number').html('Add Lyrics - <span style="color: #ccc">' + $(this)[0].song.title + '</span>')
$('#lyricsModal').foundation('reveal', 'open');
$('#add-lyrics-form').prop('action', '/albums/add-lyrics/' + id + '/save');
}
});
}]);
})();
app/routes.php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.
|
*/
Route::get('/', array('uses' => 'HomeController#hello', 'as' => 'home'));
Route::get('/login', array('uses' => 'LoginController#index', 'as' => 'login'));
Route::get('get_albums', function() {
return Album::with('songs.lyric', 'artworks', 'series')->get();
});
Route::group(array('before' => 'admin'), function() {
Route::get('/edit-albums', array('uses' => 'AlbumsController#editAlbums', 'as' => 'edit-albums'));
});
Route::group(array('before' => 'auth'), function() {
Route::group(array('prefix' => 'albums'), function() {
Route::get('/', array('uses' => 'AlbumsController#index', 'as' => 'albums-home'));
Route::get('/{slug}', array('uses' => 'AlbumsController#index', 'as' => 'albums-details'));
Route::group(array('before' => 'auth'), function() {
Route::post('/add-lyrics/{id}/save', array('uses' => 'AlbumsController#addLyrics', 'as' => 'add-lyrics'));
});
Route::group(array('before' => 'admin'), function() {
Route::get('/album/{id}/delete', array('uses' => 'AlbumsController#deleteAlbum', 'as' => 'delete-album'));
Route::get('/song/{id}/delete', array('uses' => 'AlbumsController#deleteSong', 'as' => 'delete-song'));
Route::group(array('before' => 'csrf'), function() {
Route::post('/newalbum', array('uses' => 'AlbumsController#saveAlbum', 'as' => 'save-album'));
Route::post('/add-song/{id}/new', array('uses' => 'AlbumsController#saveSong', 'as' => 'save-song'));
Route::post('/update-song/{id}/save', array('uses' => 'AlbumsController#editSong', 'as' => 'update-song'));
Route::post('/update-album/{id}/save', array('uses' => 'AlbumsController#editAlbum', 'as' => 'update-album'));
});
});
});
});
Route::group(array('prefix' => 'forum'), function() {
Route::get('/', array('uses' => 'ForumController#index', 'as' => 'forum-home'));
Route::get('/category/{id}', array('uses' => 'ForumController#category', 'as' => 'forum-category'));
Route::get('/thread/{id}', array('uses' => 'ForumController#thread', 'as' => 'forum-thread'));
Route::group(array('before' => 'admin'), function() {
Route::get('/group/{id}/delete', array('uses' => 'ForumController#deleteGroup', 'as' => 'forum-delete-group'));
Route::get('/category/{id}/delete', array('uses' => 'ForumController#deleteCategory', 'as' => 'forum-delete-category'));
Route::get('/thread/{id}/delete', array('uses' => 'ForumController#deleteThread', 'as' => 'forum-delete-thread'));
Route::group(array('before' => 'csrf'), function() {
Route::post('/category/{id}/new', array('uses' => 'ForumController#storeCategory', 'as' => 'forum-store-category'));
Route::post('/group', array('uses' => 'ForumController#storeGroup', 'as' => 'forum-store-group'));
});
});
Route::group(array('before' => 'auth'), function() {
Route::get('/thread/{id}/new', array('uses' => 'ForumController#newThread', 'as' => 'forum-get-new-thread'));
Route::group(array('before' => 'csrf'), function() {
Route::post('/thread/{id}/new', array('uses' => 'ForumController#storeThread', 'as' => 'forum-store-thread'));
});
});
});
Route::group(array('before' => 'guest'), function() {
Route::get('/user/create', array('uses' => 'UserController#getCreate', 'as' => 'getCreate'));
Route::get('/user/login', array('uses' => 'UserController#getLogin', 'as' => 'getLogin'));
Route::group(array('before' => 'csrf'), function() {
Route::post('/user/create', array('uses' => 'UserController#postCreate', 'as' => 'postCreate'));
Route::post('/user/login', array('uses' => 'UserController#postLogin', 'as' => 'postLogin'));
});
});
Route::group(array('before' => 'auth'), function() {
Route::get('/user/logout', array('uses' => 'UserController#getLogout', 'as' => 'getLogout'));
});
app/controllers/UserController.php
class UserController extends BaseController
{
//gets the view for the register page
public function getCreate()
{
return View::make('user.register');
}
//gets the view for the login page
public function getLogin()
{
return View::make('user.login');
}
public function postCreate()
{
$validate = Validator::make(Input::all(), array(
'username' => 'required|unique:users|min:4',
'pass1' => 'required|min:6',
'pass2' => 'required|same:pass1',
));
if ($validate->fails())
{
return Redirect::route('getCreate')->withErrors($validate)->withInput();
}
else
{
$user = new User();
$user->username = Input::get('username');
$user->password = Hash::make(Input::get('pass1'));
if ($user->save())
{
return Redirect::route('home')->with('success', 'You registed successfully. You can now login.');
}
else
{
return Redirect::route('home')->with('fail', 'An error occured while creating the user. Please try again.');
}
}
}
public function postLogin()
{
$validator = Validator::make(Input::all(), array(
'username' => 'required',
'pass1' => 'required'
));
if($validator->fails())
{
return Redirect::route('login')->withErrors($validator)->withInput();
}
else
{
$remember = (Input::has('remember')) ? true : false;
$auth = Auth::attempt(array(
'username' => Input::get('username'),
'password' => Input::get('pass1')
), $remember);
if($auth)
{
return Redirect::route('albums-home');
}
else
{
return Redirect::route('login')->with('fail', 'You entered the wrong login credentials, please try again!');
}
}
}
public function getLogout()
{
Auth::logout();
return Redirect::route('login');
}
}

Just create json route for logout and on success change browser url on login. For that define global function logout()
$http.get('route/to/logout').success(
window.location.href = "/login ";
});

Related

Laravel API and React js beginner here. I keep getting Error 422 in my application even though I am passing the required field

I have been trying to debug this error for a while now. I tried scouring the internet for solutions, yet I still can't find the fix for it. I am passing the required data for the API to work, but the error is still there.
Laravel Controller
protected function searchAdmin(Request $request)
{
$data = $request->validate([
'admin_ref' => 'string|required'
]);
$admin = adminInfos::where('adminID', $data['admin_ref'])->first();
if (!$admin) {
return response()->json([
'status' => '404',
'message' => $this->response['AccntNtFnd']
]);
} else {
return response()->json([
'status' => '200',
'account' => $admin
]);
}
}
React JS
const searchAdmin = (e) =>{
e.preventDefault();
axios.get(`http://127.0.0.1:8001/api/admin/adminSearch`, {
'headers':{
'Accept':'application/json',
'Content-Type':'application/json',
},
'data':{
'admin_ref': adminInput.searchInput
}
}).then(res=>{
if(res.data.status != 200){
console.log(res.data.message)
}else{
console.log(res.data.message)
}
}).catch(error => {
console.log(error.response.data)
});
}
UPDATE: I followed Nelson's advice, but the error still exists. Thank you for the advice tho, will make sure to take note of it.

How to pass array inside an api in Laravel?

When I pass array() through query it got false but when I pass without array then it show success. How can I pass array according to my code?
public function add_employee_post(Request $request){
try{
$http = new \GuzzleHttp\Client();
$employee_no = $request->employee_no;
$name = $request->name;
$nid = $request->nid;
$dob = $request->dob;
$covid_status = $request->covid_status;
$vaccine_certificate = $request->vaccine_certificate;
$official_email = $request->official_email;
$optional_email = array();
if($request->optional_email[0] != null){
foreach (json_decode($request->optional_email[0]) as $key => $email) {
array_push($optional_email, $email->value);
}
}
$official_phone = $request->official_phone;
$optional_phone = array();
if($request->optional_phone[0] != null){
foreach (json_decode($request->optional_phone[0]) as $key => $phone) {
array_push($optional_phone, $phone->value);
}
}
$designation = $request->designation;
$employee_type = $request->employee_type;
$role = $request->role;
$department = $request->department;
$team = $request->team;
$grade = $request->grade;
$level = $request->level;
$avatar = $request->avatar;
$present_address = $request->present_address;
$permanent_address = $request->permanent_address;
$employee_status = $request->employee_status;
$employee_invitation_status = $request->employee_invitation_status;
$response = $http->post('http://localhost:8000/api/v1/employees/create',[
// 'headers' => [
// 'Authorization' => 'Bearer'.session()->get('token.access_token'),
// ],
'query' =>[
'employee_no' => $employee_no,
'name' => $name,
'nid' => $nid,
'dob' => $dob,
'covid_status' => $covid_status,
'vaccine_certificate' => $vaccine_certificate,
'official_email' => $official_email,
'optional_email' => $optional_email,
'official_phone' => $official_phone,
'optional_phone' => $optional_phone,
'designation' => $designation,
'employee_type' => $employee_type,
'role' => $role,
'department' => $department,
'team' => $team,
'grade' => $grade,
'level' => $level,
'avatar' => $avatar,
'present_address' => $present_address,
'permanent_address' => $permanent_address,
'employee_status' => $employee_status,
'employee_invitation_status' => $employee_invitation_status,
]
]);
$result = json_decode((string) $response->getBody(), true);
return $result;
}
catch(\Throwable $e){
return response()->json([
'result' => false,
'message' => 'Something Error!'
]);
}
}
In same code when I comment out $optional_phone and $optional_email , it show success response but when I pass all then it show false result. How I pass an array inside query?

DB Transaction in Laravel lexical variable error

I'm currently using DB-Transaction and it throws Lexical variable error
attached here is my code:
DB::transaction(function ($request) use ($request) {
$salesman = new Salesman([
'operation_id' => $request->get('operation_id'),
'warehouse_id' => $request->get('warehouse_id'),
'salesman_name' => $request->get('salesman_name'),
'address' => $request->get('address'),
'contact_number' => $request->get('contact_number'),
'email_address' => $request->get('email_address'),
'area_id' => 'pending',
]);
$salesman->save();
});
return view('salesman.index');
}
It is working now after I remove the $request parameter in function
DB::transaction(function () use ($request) {
$salesman = new Salesman([
'operation_id' => $request->get('operation_id'),
'warehouse_id' => $request->get('warehouse_id'),
'salesman_name' => $request->get('salesman_name'),
'address' => $request->get('address'),
'contact_number' => $request->get('contact_number'),
'email_address' => $request->get('email_address'),
'area_id' => 'pending',
]);
$salesman->save();
});
return view('salesman.index');
}

angularjs unit test element $onInit binding undefined

component
import template from './account.html';
import controller from './account.controller';
import './account.less';
const accountComponent = {
bindings: {
user: '<',
onLogout: '&'
},
template,
controller
};
export default accountComponent;
controller
class AccountController {
constructor() {}
$onInit() {
this.isVisibled = false;
this.fullname = this.user.firstName + ' ' + this.user.lastName;
}
show() {
this.isVisibled = !this.isVisibled;
}
logout() {
this.onLogout();
}
}
export default AccountController;
test
import accountModule from './index';
describe('Account', () => {
beforeEach(angular.mock.module(accountModule));
let onLogoutSpy = jasmine.createSpy('onLogout');
const bindings = {
user: {
"firstName" : "me",
"lastName" : "you"
},
onLogout: onLogoutSpy
};
let controller,
rootScope,
scope;
describe('Controller', () => {
beforeEach(inject( ($injector) => {
rootScope = $injector.get('$rootScope');
scope = rootScope.$new();
const $componentController = $injector.get('$componentController');
controller = $componentController('appAccount',{$scope:scope},bindings);
controller.$onInit();
}));
it('should be attached to the scope', () => {
expect(scope.$ctrl).toBe(controller);
});
it('isVisibled should be false', () => {
expect(controller.isVisibled).toBe(false);
});
it('fullname should be me you', () => {
expect(controller.fullname).toEqual('me you');
});
it('isVisibled should be true', () => {
controller.show();
expect(controller.isVisibled).toBe(true);
});
it('should onLogout have been called', () => {
controller.logout();
expect(onLogoutSpy).toHaveBeenCalled();
});
});
describe('Component', () => {
let element,scope;
beforeEach(inject(($rootScope, $compile) => {
dump(bindings.user);
scope = $rootScope.$new();
const markup = `
<app-account user="bindings.user"></app-account>
`;
element = angular.element(markup);
element = $compile(element)(scope);
let elementController = element.controller('app-account');
scope.$digest();
elementController.$onInit();
}));
it('xxx', () => {
//dump(element);
//const backendHeader = element.find('backend-header').eq(0);
//expect(backendHeader).toBeDefined();
});
});
});
Give me
1) xxx
Account Component
TypeError: Cannot read property 'firstName' of undefined
Can you help me to work it out, please?
I think you should write :
beforeEach(inject(($rootScope, $compile) => {
scope = $rootScope.$new();
scope.user = {
firstName "me",
lastName : "you"
}
element = $compile(`<app-account user="user"></app-account>`)(scope);
let elementController = element.controller('app-account');
scope.$digest();
}));
You're passing the user obj of the bindings object, it must be the user obj of the scope.
You do not assign bindings to the scope in your second test
scope = $rootScope.$new();
scope.bindings = bindings; // -------v
const markup = '<app-account user="bindings.user"></app-account>';

Trying to do a unit test for a controller with $state

I am trying to write some unit tests for my Angular 1.5 components based on this tutorial.
import notificationBannerTemplate from 'app/components/notification-banner/notification-banner.html';
const notificationBanner = {
templateUrl: notificationBannerTemplate,
controller: notificationBannerController,
bindings: {
user: '<notificationBannerUser',
onNotificationClick: '<notificationBannerOnNotificationClick',
},
};
notificationBanner.$inject = ['$state'];
function notificationBannerController($state) {
const ctrl = this;
ctrl.$onInit = function() {
ctrl.goToProfile = goToProfile;
};
function goToProfile() {
ctrl.onNotificationClick();
$state.go('app.profile.settings');
}
}
export default notificationBanner;
And my test looks like this:
import unitHelpers from 'test/unit/unit-helpers.js';
describe('notificationBanner component', () => {
let parentScope;
let element;
let state;
const $stateMock = {};
beforeEach(() => {
angular.mock.module(($provide) => {
$provide.value('$state', $stateMock);
});
});
beforeEach(angular.mock.module('CustomerComponentsModule'));
beforeEach(inject(($compile, $rootScope) => {
parentScope = $rootScope.$new();
state = jasmine.createSpyObj('$state', ['go']);
parentScope.user = {
email: 'test#test.com',
};
parentScope.closeBanner = function() {
};
element = angular.element(
`<notification-banner
notification-banner-user="user"
notification-banner-on-notification-click="closeBanner">
</notification-banner>`);
$compile(element)(parentScope);
parentScope.$digest();
}));
it('should call the goToProfile function when the button is clicked', () => {
const componentElement = unitHelpers.findByTestId(element, 'bounced-email-banner--button');
componentElement.click();
expect(state.go).toHaveBeenCalledWith('app.profile.settings');
});
});
I've tried a few different things from what I've read online, but every time I run my test I get the error TypeError: undefined is not a constructor (evaluating '$state.go('app.profile.settings')')
How can I test this?
Figured out the problem --- had to add a 'go' method to my $stateMock.
const $stateMock = {
go: jasmine.createSpy('go'),
};
Then I was able to test with expect($stateMock.go).toHaveBeenCalledWith('app.profile.settings');

Resources