1

So I have the following service/factory setup that should query a JSON file:

myappServices.factory('Result', ['$resource',
    function($resource){
        return $resource('search.json', {}, {
            query: { method:'GET', params: {}, isArray:true }
        });
    }]);

And then in my SearchCtrl I have:

    myappControllers.controller('SearchCtrl', function($rootScope, $scope, $state, Result, $location) {

    $scope.query = ($state.includes('search') ? $location.search()['q'] : '');
    $scope.filterQuery = ($state.includes('search') ? $location.search()['q'] : '');

    $scope.queryChanged = function () {
        if($scope.query){
            $state.go('search', {'q': $scope.query} );
            $scope.results = Result.query();
        } else {
            $location.search('q', null);
        }
        $scope.filterQuery = $scope.query;
    }

    if($scope.query){
        $scope.results = Result.query();
    } else {
        $location.search('q', null);
    }

});

The search results page looks like:

<ul class="ng-hide" ng-show="results.length > 0">
    <li ng-repeat="result in results">
        <a href="{{result.url}}">{{result.name}}</a>
        <p>{{result.snippet}}</p>
    </li>
</ul>

<p class="ng-hide" ng-show="results.length == 0">Nothing here!</p>

If I do a query like:

/search?=hello

Then ALL the results in the JSON file are returned REGARDLESS of what I have searched for (should only be showing results that match).

However if I don't do a query then no results are shown (correct behaviour).

Why is the query not being used against the JSON file to filter the results?


I did originally have the repeater as:

<li ng-repeat="result in results = ( results | filter:filterQuery )">

But that would be incorrect in this case, as it's would be saying show me the results but filter them using the filterQuery. But in reality there would never be any results if no query, hence removing this part of the repeater. As I don't want to filter a list but return a list filtered.


So it would seem I am missing something in my service to handle this.

3 Answers 3

1

Edited: Simplify your resource so it doesn't define query:

myappServices.factory('Result', ['$resource',
    function($resource){
        return $resource('search.json');
    }]);

Try changing your controller to clear the results and only set them when a query has been made:

myappControllers.controller('SearchCtrl', function($rootScope, $scope, $state, Result, $location) {

    $scope.query = ($state.includes('search') ? $location.search()['q'] : '');
    $scope.filterQuery = ($state.includes('search') ? $location.search()['q'] : '');

    $scope.results = [];
    $scope.queryChanged = function () {
        if($scope.query){
            $state.go('search', {'q': $scope.query} );
        } else {
            $scope.results = Result.query({q:$scope.query});
        }
        $scope.filterQuery = $scope.query;
    }
});
Sign up to request clarification or add additional context in comments.

7 Comments

Using the get instead of the query causes this error: Error: [$resource:badcfg] Error in resource configuration. Expected response to contain an object but got an array
Then you need to use the query() method, but there's no need to define it in your code. Use the default method instead.
If the query is search?q=Vision then in the console I see: "http://ang.com/search.json?0=V&1=i&2=s&3=i&4=o&5=n". so it's messing up the query...
Just to confirm that Angular should be filtering the results and that ang.com isn't a web service that will be filtering that json results based on any passed query strings!
Edited the code to pass {q:$scope.query} to the query() method
|
1
app.factory('querySvc', ['$q', '$resource', querySvc]);

function querySvc($q, $resource) {
    var service = {
         getSearch: getSearch
    }
    return service;

 function getSearch(){
    var deferred = $q.defer();

    $resource('search.json').query( function(data){
         deferred.resolve(data);
    }, function(error){
         // handle error
    });
    return deferred.promise;
 }

Then you can call it that way:

 querySvc.getSearch().then(function (data){
     $scope.results = data;
 }, function(error){
     //handle error here
 });

About your first note : When you instantiate your controller, it executes everything inside it.

So, if you want to call this function when a user clicks somewhere, you can register a function into the scope :

$scope.querySearch = function(){
     querySvc.getSearch().then(function (data){
         $scope.results = data;
     }, function(error){
         //handle error here
     });
}

And then, into your view, you will have to call it when an event is fired. I don't remember the event you need, but I'll show you a way of doing it :

<span ng-click="querySearch()" />

This will trigger the function when you click on the span.

2 Comments

Doing that gives me an error that undefined is not a function.
I've edited my answer with the way I use $resource inside a factory and $q. I hope it will suit you.
0

In the console, look in the Network tab to see if the request has an error and/or to see the contents of the response. If the response has a status code of 200 and the contents are correct, then check the response to see if the data is structured correctly for results.length (that it returns a list).

4 Comments

If I don't have a query then I see the whole contents of the JSON file, so the issue isn't with the request, rather using the query param and only showing results if I have.
Try displaying {{ results }} to see what it contains.
If I go to search I see the results as JSON, but with search?q=vision I don't see any results. I shouldn't see any results if I don't have a query, so it's defaulting incorrectly too.
The default case happens when $scope.results = Result.query(); is executed. Move that line inside the queryChanged function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.