Filter from external source in AngularJS custom DataTable
<p>I have a custom data table in my AngularJS application.</p>

<p>App.js :</p>

<pre><code>myApp.factory('dataTable', ['$filter', 'ngTableParams', '$rootScope', function ($filter, ngTableParams, $rootScope) {

    var factoryDefinition = {
      render: function($scope, config, componentId, data) {

        if(!config) config ={};
        var config = angular.extend({}, {page:1, count:10}, config)

        $scope[componentId] = new ngTableParams(config, {
            total: data.length, // length of data
            getData: function ($defer, params) {
                // organize filter as $filter understand it (graph object)
                var filters = {};
                var val = $rootScope.mysearch;
                var key = "firstname";
                angular.forEach(params.filter(), function (val, key) {
                    var filter = filters;
                    var parts = key.split('.');
                    for (var i = 0; i &lt; parts.length; i++) {
                        if (i != parts.length - 1) {
                            filter[parts[i]] = {};
                            filter = filter[parts[i]];
                        }
                        else {
                            filter[parts[i]] = val;
                        }
                    }
                });
                // use build-in angular filter
                var filteredData = params.filter() ?
                        $filter('filter')(data, filters) :
                        data;
                var orderedData = params.sorting() ?
                        $filter('orderBy')(filteredData, params.orderBy()) :
                        data;
                params.total(orderedData.length); // set total for recalc pagination
                $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
                $scope.pageNumber = params.page();
                $scope.itemsPerPage = params.count();
            }
        }); 


      }
    }

    return factoryDefinition;
  }
]);
</code></pre>

<p>I understand that the filter is applied in the <code>params.filter(), function (val, key)</code> and 'val' returns the value and 'key' returns the name of the filter. </p>

<p>HTML :</p>

<pre><code>&lt;div class="widget-content  table-container" ng-controller="getEmployeesController" &gt;

                &lt;table ng-table="employeesList" show-filter="true" class="table table-striped table-bordered"&gt;
                    &lt;tr ng-repeat="employee in $data"&gt;
                        &lt;td data-title="'#'"&gt;
                           {{ (itemsPerPage * (pageNumber-1)) + $index+1 }}
                        &lt;/td&gt;
                        &lt;td data-title="'First Name'" sortable="'firstName'" filter="{ 'firstName': 'text' }"&gt;
                            {{employee.firstName}}
                        &lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
</code></pre>

<p>Filtering is working fine from within the data table. But I want it to set filter based on search string in another controller.</p>

<p>The controller is :</p>

<pre><code>myApp.controller('getUserHeader', ['$scope', 'commonServices', 'dataTable', '$window', '$rootScope', '$location', '$filter', function ($scope, commonServices, dataTable, $window, $rootScope, $location, $filter) {
    commonServices.getReservations().then(function (result) {
        $scope.data = result.data;
        $scope.data.userName = $rootScope.userInfo.UserName;
        $scope.data.userId = $rootScope.userInfo.UserId;
        commonServices.getEmployee($scope.data.userId).then(function (result) {
            $scope.data = result.data;
        });
        $scope.applySearch = function () {

            $rootScope.mysearch = $scope.mysearch;
            $rootScope.null = null;

            $location.path("/employees");
        }
});
}]);
</code></pre>

<p>The function <code>applySearch</code> is invoked when user types in the filter string and it is saved in to $rootscope and is accessible from all the controllers.</p>

<p>I saved this value in to keyword 'val' and set the value for 'key' as "firstname" inside the controller. On entering the string, the page will redirect to <code>$location.path("/employees");</code> where the data table is present.The values are getting in to the controller <code>myApp.factory('dataTable')</code> but the filtering is not happening. The control breaks at <code>angular.forEach(params.filter(), function (val, key) {</code>. Its not returning any error message. </p>

<p>Can someone tell me how I can manually pass these values in to the DataTable directive to get this working?</p>

<p>I will share some screen shots of the console to show you what is going on there. Sadly I don't know how to create a plunker out of this.</p>

<p>While filtering from within the data table:<a href="https://i.stack.imgur.com/7r9h5.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/7r9h5.jpg" alt=""></a></p>

<p>While trying to filter from the external search bar :
<a href="https://i.stack.imgur.com/BfJUl.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/BfJUl.jpg" alt="enter image description here"></a></p>

<p>The filtering is working fine in first case. But its not happening in the second case. Hope I explained my situation well and provided all the required data.</p>

<p><strong>UPDATE</strong> : </p>

<p>I was able to make a little improvement by hard coding the filter directly in to the DataTable directive.</p>

<p>Added   <code>if (!config) config = { filter: { 'firstName': $rootScope.mysearch } };</code> inside the function as follows.</p>

<p>App.js :</p>

<pre><code>//Datatable
myApp.factory('dataTable', ['$filter', 'ngTableParams', '$rootScope', function ($filter, ngTableParams, $rootScope) {

    var factoryDefinition = {
      render: function($scope, config, componentId, data) {
          if (!config) config = { filter: { 'firstName': $rootScope.mysearch } };

        var config = angular.extend({}, {page:1, count:10}, config)

        $scope[componentId] = new ngTableParams(config, {
            total: data.length, // length of data
            getData: function ($defer, params) {
                // organize filter as $filter understand it (graph object)
                var filters = {};
                var val = $rootScope.mysearch;
                var key = "firstname";

                angular.forEach(params.filter(), function (val, key) {
                    var filter = filters;
                    var parts = key.split('.');
                    for (var i = 0; i &lt; parts.length; i++) {
                        if (i != parts.length - 1) {
                            filter[parts[i]] = {};
                            filter = filter[parts[i]];
                        }
                        else {
                            filter[parts[i]] = val;
                        }
                    }
                });
                // use build-in angular filter
                var filteredData = params.filter() ?
                        $filter('filter')(data, filters) :
                        data;
                var orderedData = params.sorting() ?
                        $filter('orderBy')(filteredData, params.orderBy()) :
                        data;
                params.total(orderedData.length); // set total for recalc pagination
                $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
                $scope.pageNumber = params.page();
                $scope.itemsPerPage = params.count();
            }
        }); 


      }
    }

    return factoryDefinition;
  }
]);
</code></pre>

<p>The datatable now filters fine as expected but I don't want it to be hardcoded. I want to inject the filter instead of hardcoding it probably inside the controller. How am I supposed to inject it?  </p>