J. West J. West - 10 months ago 44
Ajax Question

jQuery, AJAX and AngularJS

I'm changing a Spring app from Thymeleaf to AngularJS (learning as I go) and this Ajax call that was previously working is now not even registering on in Chrome XHR. I don't have a lot of experience with these front-end frameworks so I'm not sure what changed.


<!doctype html>
<html ng-app="wishingWell">
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/css/normalize.css">

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-route.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.js" integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA=" crossorigin="anonymous"></script>
<script src="/javascript/app.js"></script>

<title>Wishing Well</title>

<nav class="nav">
<ul class="navback">
<a class="active" href="#/">The Well</a>
<a href="#/profile" >Profile</a>
<a href="#/sign-up">Sign Up</a>
<a href="#/login">Log In</a>
<a href="#/logout">Sign Out</a>

<div ng-view></div>

jQuery(document).ready(function($) {

$("#wish-form").submit(function(event) {

// Disble the search button

// Prevent the form from submitting via the browser.




function searchViaAjax() {

var search = {}
search["wish"] = $("#wish").val();

type : "POST",
contentType : "application/json",
url : "/addwish",
data : JSON.stringify(search),
dataType : 'json',
timeout : 100000,
success : function(data) {
console.log("SUCCESS: ", data);
error : function(e) {
console.log("ERROR: ", e);
done : function(e) {


function enableSearchButton(flag) {
$("#btn-submit").prop("disabled", flag);

function display(data) {
var jsonString = JSON.stringify(data);
var json = JSON.parse(jsonString);

$('#feedback').fadeOut(300, function(){



var wishingWell = angular.module('wishingWell', [ 'ngRoute' ]);

wishingWell.config(function($routeProvider, $httpProvider) {

$routeProvider.when('/', {
templateUrl : 'home.html',
controller : 'home',
controllerAs: 'controller'
}).when('/login', {
templateUrl : 'login.html',
controller : 'navigation',
controllerAs: 'controller'

$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';



function($rootScope, $http, $location) {

var self = this

var authenticate = function(credentials, callback) {

var headers = credentials ? {authorization : "Basic "
+ btoa(credentials.username + ":" + credentials.password)
} : {};

$http.get('user', {headers : headers}).then(function(response) {
if (response.data.name) {
$rootScope.authenticated = true;
} else {
$rootScope.authenticated = false;
callback && callback();
}, function() {
$rootScope.authenticated = false;
callback && callback();


self.credentials = {};
self.login = function() {
authenticate(self.credentials, function() {
if ($rootScope.authenticated) {
self.error = false;
} else {
self.error = true;

My guess is that something within AngularJS is overriding jQuery, but I can't figure out what. Most of the questions about this I've seen relate to using jQuery Ajax within an AngularJS controller, but it seems like it should work outside. Also, the form data being submitted via Ajax gets put into the ng-view.

Answer Source

There a a few things amiss here:

  • The jQuery(document).ready(function($) is fired when the browsers emits the DOMContentLoaded. ng-view is an asynchronous fetch operation. So, most likely, when the jQuery ready function is triggered to attach your callback upon submit, the ng-view fetch operation of your template hasn't even been completed. So this would fail.
  • It's not best practice to mix jQuery AJAX in your Angular code. The reasons are many for this, but it is mostly because the DOM manipulation paradigm in AngularJS and jQuery are completely different, as can be seen by the point above.
  • What I would advise is for you to convert your AJAX calls to Angular $http requests, within a service. Services are bound to the application and can be used app wide. This will create a clean separation of concerns and avoid the jQuery - Angular race condition

The searchViaAjax can be moved to be within a controller, like so:

$scope.searchViaAjax = function() {
  $scope.search.searchResults =  SearchService.search($scope.search.searchText);
  // Where SearchService is a service you define app level, and inject into your controller

<input ng-model="search.searchText">
  <li ng-repeat="searchResult in search.searchResults">{{searchResult.text}}</li>

And so on.