0

(was not sure what to have as a title, so if you have a better suggestion, feel free to come up with one - I will correct) I am working on an angular application where I have some menues and a search result list. I also have a document view area. You can sort of say that the application behaves like an e-mail application.

I have a few controllers:

DateCtrl: creates a list of dates so the users can choose which dates they want to see posts from.

SourceCtrl: Creates a list of sources so the user can choose from which sources he/she wants to see posts from.

ListCtrl: The controller populating the list. The data comes from an elastic search index. The list is updated every 10-30 seconds (trying to find the best interval) by using the $interval service.

What I have tried Sources: I have tried to make this a filter, but a user clicks two checkboxes the list is not sorted by date, but on which checkbox the user clicked first. If it is possible to make this work as a filter, I'd rather continue doing that. The current code is like this, it does not do what I want:

.filter("bureauFilter", function(filterService) {
        return function(input) {
            var selectedFilter = filterService.getFilters();

            if (selectedFilter.length === 0) {
                return input;
            }

            var out = [];

            if (selectedFilter) {
                for (var f = 0; f < selectedFilter.length; f++) {
                    for (var i = 0; i < input.length; i++) {
                        var myDate = input[i]._source.versioncreated;

                        var changedDate = dateFromString(myDate);
                        input[i]._source.sort = new Date(changedDate).getTime(); 

                        if (input[i]._source.copyrightholder === selectedFilter[f]) {
                            out.push(input[i]);
                        }


                    }
                }
                // return out;

                // we need to sort the out array
                var returnArray = out.sort(function(a,b) {
                    return new Date(b.versioncreated).getTime() - new Date(a.versioncreated).getTime();
                });

                return returnArray;
            } else {
                return input;
            }


        }
    })

Date: I have found it in production that this cannot be used as a filter. The list of posts shows the latest 1000 posts, which is only a third of all posts arriving each day. So this has to be changed to a date-search.

I am trying something like this:

.service('elasticService', ['es', 'searchService', function (es, searchService) {
    var esSearch = function (searchService) {
        if (searchService.field === "versioncreated") {
// doing some code
} else {
 // doing some other type of search 
}

and a search service:

.service('searchService', function () {
    var selectedField = "";
    var selectedValue = "";

    var setFieldAndValue = function (field, value) {
        selectedField = field;
        selectedValue = value;
    };

    var getFieldAndValue = function () {
        return {
            "field": selectedField,
            "value": selectedValue
        }
    };

    return {
        setFieldAndValue: setFieldAndValue,
        getFieldAndValue: getFieldAndValue
    };
})

What I want to achieve is this: When no dates or sources are clicked the whole list shall be shown. When Source or Date are clicked it shall get the posts based on these selections. I cannot use filter on Date as the application receives some 3000 posts a day and so I have to query elastic search to get the posts for the selected date.

Up until now I have put the elastic-search in the listController, but I am now refactoring so the es-search happens in a service. This so the listController will receive the correct post based on the selections the user has done.

Question is: What is the best pattern or method to use when trying to achieve this?

1 Answer 1

1

Where your data is coming from is pretty irrelevant, it's for you to do the hook up with your data source.

With regards to how to render a list:

The view would be:

<div ng-controller='MyController as myCtrl'>
  <form>
    <input name='searchText' ng-model='myCtrl.searchText'>
  </form>
  <ul>
    <li ng-repeat='item in myCtrl.list | filter:myCtrl.searchText' ng-bind='item'></li>
  </ul>
  <button ng-click='myCtrl.doSomethingOnClick()'>
</div>

controller would be:

myApp.controller('MyController', ['ElasticSearchService',function(ElasticSearchService) {
  var self = this;
  self.searchText = '';
  ElasticSearchService.getInitialList().then(function(list) {
    self.list = list;
  });

  self.doSomethingOnClick = function() {
    ElasticSearchService.updateList(self.searchText).then(function(list) {
      self.list = list;
     });
  }
}]);

service would be:

myApp.service('ElasticSearchService', ['$q', function($q) {

var obj = {};
obj.getInitialList = function() {
    var defer = $q.defer();
    // do some elastic search stuff here
    // on success
    defer.resolve(esdata);
    // on failure
    defer.reject();
    return defer.promise();
  };

  obj.updateList = function(param) {
    var defer = $q.defer();
    // do some elastic search stuff here
    // on success
    defer.resolve(esdata);
    // on failure
    defer.reject();
    return defer.promise();
  };
return obj;
}]);

This code has NOT been tested but gives you an outline of how you should approach this. $q is used because promises allow things to be dealt with asynchronously.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the valuable input danday74. Because of your answer I was able to solve the problem. I looked at your code + did a search on promise + angularjs and found this site: sitepoint.com/building-recipe-search-site-angular-elasticsearch which shows how to do it. But would not have found and understood the code without your input.

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.