Sending AJAX request from Angular to Laravel

So you have decided to use Angular as your client side framework and it is common practice to use Ajax in modern web applications, here comes the hard part, you are trying to send Ajax request to Laravel 5.1 but it keeps failing for some reason and you can't figure it out and keep thinking "It was so easy in jQuery", let's figure it out.

We are going to create a simple search application which shows users email, city and Phone No. of searched user. 

Here is what we are going to build-

This tutorial will demonstrate how to send AJAX request from AngularJS to Laravel and get user information based on username. To do so, We will create a simple search form and when it is submitted or being typed we will send the AJAX request to Laravel and get user information.

Ajax request from AngularJs to Laravel 5

Creating appropriate Routes -

We will use home page ('/') as our landing page, this page will have our form and it will also display user information when AJAX request is completed, We also going to create route for our search API which we will use in our angular code.

<?php


Route::get('/', function() {
    return view('ajax.search');
});

//Route for our Search Api 
Route::group([ 'prefix' => 'api'], function() {
    Route::post('/search', ['uses' => 'SearchController@search', 'as' => 'search.ajax']);
});

Creating Views -

This is very small application and only created for demonstration so we don't need lots of views, we are going to create a master page (master.blade.php) and view('search.blade.php'), there is no need of master page for this small app but still it's good practice and it will also keep things really neat.

master.blade.php

We are going to pull Angular, Bootstrap and jQuery from CDN to keep everything simple, We also need custom search.js file where we will put our angular code. We have included meta tag where we are generating csrf token for later use in our angular code.

<!doctype html>
<html lang="en" ng-app="App">
<head>
    <meta charset="UTF-8">
    <meta name="_token" content="{{ csrf_token() }}"/>
    <title>Document</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
    <style>
        body {
            padding-top : 70px;
        }
    </style>
</head>
<body>
    <div class="container">
        @yield('content')
    </div>

    <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="js/search.js"></script>
</body>
</html>

search.blade.php

In our search view We have created Input to search user information,  We have created a controller named SearchCtrl in angular where we will put our search logic, we have also associated searchInput model with our input box.

Once the form is submitted or we start typing, Search function will be called and  it will fetch user information.

At last we have the simple template to print user information, it is simple list group from bootstrap and will be shown only if the result is found.

@extends('master')

@section('content')
    <div class="row" ng-controller="SearchCtrl">
        <div class="col-md-6 col-md-offset-3" >
            <div class="row">
                <form method="GET" ng-submit="search()">
                    <div class="input-group">
                        <input type="text" class="form-control" ng-keyup="search()" placeholder="Enter use name to search.." ng-model="searchInput">
                          <span class="input-group-btn">
                            <button class="btn btn-default" type="submit" >Search</button>
                          </span>
                    </div><!-- /input-group -->
                </form>
            </div>
            <div class="row" style="margin-top : 100px">
                <div class="list-group" ng-if="results">
                    <a href="#" class="list-group-item active">
                        <h4 class="list-group-item-heading">Name : @{{ searchInput }}</h4>
                        <p class="list-group-item-text">Email : @{{ userInfo.email }}</p>
                        <p class="list-group-item-text">City : @{{ userInfo.city }}</p>
                        <p class="list-group-item-text">Phone : @{{ userInfo.phone }}</p>
                    </a>
                </div>
            </div>

        </div>
    </div>


@stop

Creating SearchController.php in Laravel( Generate this controller using artisan command )-

We also have created SearchController in Laravel, for the sake of simplicity we are not going to create any Model or any database connection, We have a simple array of Users which we are going to search from.

SearchController contains search method where we are doing some simple checking such as if the request is XMLHTTPRequet(AJAX) or not. After that, we are checking if the user exists in the array and if found, We will echo it as JSON object using PHP json_encode function else we will echo invalid user.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

class SearchController extends Controller
{
    private $users_info = array();

    public function __construct()
    {
        $this->users_info = $this->getUsersInfo();

    }
    public function search( Request $request )
    {
        if( $request->isXmlHttpRequest())
        {
            if(array_key_exists($request->get('name'), $this->users_info))
            {
                return json_encode($this->users_info[$request->get('name')]);
            }
            else
            {
                return 'Invlid User';
            }
        }


    }


    private function getUsersInfo()
    {
        return array(
            'user1' => array("email"=>"lacus.Quisque@Cumsociisnatoque.co.uk","city"=>"Santa Luzia","phone"=>"1-662-972-3029"),
            'user2' => array("email"=>"Nunc@utpellentesque.ca","city"=>"Hull","phone"=>"1-626-216-6913"),
            'user3' => array("email"=>"ipsum.Phasellus@leoinlobortis.ca","city"=>"Verrayes","phone"=>"1-596-787-2115"),
            'user4' => array("email"=>"at.nisi.Cum@odiosemper.org","city"=>"Issime","phone"=>"1-213-921-4792"),
            'user5' => array("email"=>"amet.consectetuer.adipiscing@consectetueradipiscing.edu","city"=>"Ternitz","phone"=>"1-220-402-3545"),
            'user6' => array("email"=>"aliquam@amet.co.uk","city"=>"Rapagnano","phone"=>"1-700-992-4247"),
            'user7' => array("email"=>"Aenean@duiaugue.com","city"=>"Sooke","phone"=>"1-550-973-6185"),
            'user8' => array("email"=>"tincidunt.adipiscing.Mauris@risusNunc.com","city"=>"Winnipeg","phone"=>"1-745-752-1099"),
            'user9' => array("email"=>"sed.tortor@nonsapienmolestie.com","city"=>"Pitt Meadows","phone"=>"1-160-446-5979"),
            'user10' => array("email"=>"sed.est@Pellentesqueultriciesdignissim.co.uk","city"=>"Weyburn","phone"=>"1-927-860-7097"),
            'user11' => array("email"=>"Nulla.facilisis.Suspendisse@sagittislobortis.co.uk","city"=>"Ficulle","phone"=>"1-818-149-5678"),
            'user12' => array("email"=>"faucibus.lectus.a@mattisCras.co.uk","city"=>"L´┐Żbeck","phone"=>"1-965-561-7243"),
            'user13' => array("email"=>"egestas.blandit.Nam@Duisa.net","city"=>"Dorval","phone"=>"1-252-518-0468"),
            'user14' => array("email"=>"magna.Nam.ligula@imperdietnec.org","city"=>"Sosnowiec","phone"=>"1-560-833-7645"),
            'user15' => array("email"=>"lacinia@semegestasblandit.net","city"=>"Conselice","phone"=>"1-358-995-6876")
        );
    }

}

Creating public/js/serach.js-

This file will bootstrap our angular code and will also contain SearchCtrl which will contain our search logic.

Laravel requires following information header-

X-CSRF-TOKEN -  To prevent us from Cross-site request forgery, Laravel requires a csrf token to validate the request.

X-Requested-With - Laravel's isXmlHttpRequest function requires this header data to determine if the request is AJAX.

Content-Type - We need to tell Laravel that our content type is application/x-www-form-urlencoded.

While bootstrapping our angular application we will set these headers, so we don't have to do it later manually.

var app = angular.module('App', [], ['$httpProvider', function($httpProvider) {
    //Setting headers
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
    $httpProvider.defaults.headers.common['X-Requested-With'] = "XMLHttpRequest";
    $httpProvider.defaults.headers.post['X-CSRF-TOKEN'] = $('meta[name=_token]').attr('content');
}]);

app.controller('SearchCtrl', function($scope, $http) {

    $scope.search = function() {
        //go further if only word lenght is greater then or equal to 3
        if($scope.searchInput.length < 3)
        {
            return;
        }
        //firing ajax request
        var promise = $http({
            method: 'POST',
            
            //setting url for search ( we have this route in routes.php )
            url: 'api/search',
            //setting object inside param function that will be sent 
            data: $.param({ 'name' : $scope.searchInput })
        });

        promise.success(function (data, status, header, config) {
            if(data == 'Invalid User')
            {
                $scope.results = false;
            }
            else {
                $scope.results = true;
                $scope.userInfo = data;
            }
        });

    };
});

That's all folks, it should be enough to send AJAX request which Laravel understands, if you are having trouble, tell us in the comment section below or create the new thread in the forum.  

Something to say? Tell us in comment section.