I am implementing an advanced search in an application I'm working on. In this search I want the back and next buttons from the browser to work with the search.
To achieve this I added this to my $routeProvider:
.when('/search', {
templateUrl: 'Scripts/App/Views/Search.html',
controller: 'SearchController',
reloadOnSearch: false
})
In my SearchController I have a search function on the $scope that just adds some query string parameters to my URL:
$scope.advancedSearch = function(){
$location.search("page", $scope.currentPage);
$location.search("groupingField", $scope.groupingField);
$location.search("topgroup", angular.toJson($scope.filter));
}
I listen to $routeUpdate, get the query string parameters and execute the search with these parameters.
$scope.$on('$routeUpdate', function () {
var qs = $location.search();
var topGroup = qs["topgroup"];
$scope.filter = angular.fromJson(topGroup);
$scope.groupingField = qs["groupingField"];
$scope.currentPage = qs["page"];
performSearch();
});
In my real search method I check the form for errors. If there are any I show a message else I perform the search (do an API call).
var performSearch = function () {
if ($scope.searchForm.$invalid) {
$scope.message = "Please fix the errors before you search.";
} else {
//get search results from database and put them on $scope.
}
}
With this code I can search and get the correct results. If I do a new search it also get's the correct results and I can use the back and next buttons from the browser.
When I do a search and my form is invalid the message shows, but when I go back after an invalid search the $invalid of the form updates after my "performSearch" method is called. This causes "Please fix the errors before you search." message to display even if the form is $valid.
If I click on the next button after this I get even more trouble since the form is $valid now but with the querystring parameters filled in it should be $invalid. Again this only updates after the performSearch has been called. which is to late.
It might be hard to understand my problem, if something is unclear ask away!
Found the answer! On the $routeupdate I waited for a digest cycle to finish and update the form properties. This can be done with a $timeout without a time.
$scope.$on('$routeUpdate', function () {
var qs = $location.search();
var topGroup = qs["topgroup"];
$scope.filter = angular.fromJson(topGroup);
$scope.groupingField = qs["groupingField"];
$scope.currentPage = qs["page"];
$timeout(function () {
performSearch();
});
});