1

I have a simple template with an input and an anchor link which, upon pressing it, will load another template. I want this second template to fetch the information via a http request.

I am using ng-route to redirect to the search template by default and to the results template from the path /search/:title, and I am trying to use resolve to make the request before loading the results template (code in plunker)

The main problem I am facing is that when I add the resolve the controller stops being initialized (I guess it will load after the promise is returned). This means variables such as the search URL are not initialized and the $routeParams are empty when I print them on the controller search function.

How should I do this?

I am also not sure about the correct syntax for the resolve. Is the first search a scope variable?

resolve: {
    search: searchController.search 
}

For the ones lazy to check on Plunker, here it is the relevant code:

Routing

.config(['$routeProvider',function($routeProvider) {
    $routeProvider.
      when('/search', {
        templateUrl: 'templates/search.html'
      }).
      when('/search/:title', {
        templateUrl: 'templates/result.html',
        controller: 'searchController', 
        resolve: {
            search: searchController.search
        }
      }).
      otherwise({
        redirectTo: '/search'
      });
  }]); 

searchController

var searchController = search.controller('searchController', ["$http", "$scope", "$location", '$rootScope', '$routeParams', function($http, $scope, $location, $rootScope, $routeParams) {
    console.log("Controller constructor");
    this.searchURL = 'http://www.myapifilms.com/imdb?title=%thetitle%&format=JSON';
    $scope.response = '<Response here>';
    this.title = '';
    this.defer = null;
    console.log("PARAMS: " + JSON.stringify($routeParams));
    }]);

    searchController.search = function searchMovie($q, $routeParams) {
        searchController.defer = $q.defer;

        var searchString = $routeParams.title;
        url = searchController.searchURL.replace('%thetitle%', searchString);
        console.log("URL: " + url);
        searchController.searchRequest(url);
    };

    searchController.searchRequest = function(url) {
        $http.get(url).success(function(data) {
            ....
            searchController.defer.resolve(); 
            return searchController.defer.promise;
        })
        .error(function(data, status, headers, config) {
            ...
            searchController.defer.resolve(); 
            return searchController.defer.promise;
        })
    };
momo
  • 3,404
  • 6
  • 37
  • 66

1 Answers1

2

I think you should create a service with .factory and edit accordingly:

angular.module('myApp', ['ionic', 'ngRoute', 'starter', 'wc.Directives'])

.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if (window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if (window.StatusBar) {
      StatusBar.styleDefault();
    }
  })
})

.factory("search", function($q, $http){
    return {
        getMessage: function(){
            //return $q.when("Response");
            var promise = $http({ method: 'GET', url: 'your_url'}).success(function(data, status, headers, config) {
                 return data;
             });
             return promise;
        }
    };
})

.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
    when('/search', {
      templateUrl: 'search.html'
    }).
    when('/search/:title', {
      templateUrl: 'result.html',
      controller: 'searchController',
      /*resolve: {
        search: searchController.search
      }*/
      resolve: {
            search: function(search){
                return search.getMessage();
        }
      }
    }).
    otherwise({
      redirectTo: '/search'
    });
  }
]);

Your plunker forked: http://plnkr.co/edit/Ry4LAl?p=preview

I hope you got what you wanted, share back your plunker after you are done for helping others.

Sameer Shemna
  • 886
  • 10
  • 19
  • Thanks for the answer Sammeer. I don't really understand what you did there. You create a factory that does something (I don't get what $q.when is), and then call it from the resolve. Where should the http request be in this? Why there are not any defer and promise calls? Can I just make the request from the controller? – momo Oct 09 '14 at 07:08
  • 1
    $q returns a promise just like $http request, check my editions. – Sameer Shemna Oct 09 '14 at 07:16
  • Thanks again. Last question, Can I put the http request in the controller? And, is it needed to keep nesting functions like that? Coming from a non Javascript background all this looks so weird... – momo Oct 09 '14 at 07:27
  • 1
    Whoa! you have got some balls getting your hands on Angular coming from a non Javascript background. As for your question, sure you can updated the plunker for you: http://plnkr.co/edit/Ry4LAl?p=preview if it solves your problem, mark my answer as accepted. Cheers! – Sameer Shemna Oct 09 '14 at 13:19
  • Haha, I am an Android and iOS dev but my company is moving towards a Hybrid approach (web + native wrapper) and using Ionic + AngularJS + Cordova. A real pain for me :-P Anyway, I think your answer put me in the right track, thanks – momo Oct 10 '14 at 02:34