0

Orderby works when the page first loads, with the default value set in scope. But then value for the Order By changes, the sort order does not change. The option selector does assign the correct value upon selection and I have verified that. But no change in the sort order.

Here is how I have my select options defined:

<md-toolbar>
<div>
        <section layout-align="end center" layout="row" flex="40">
            <md-input-container>

              <md-select ng-model="sort" placeholder="Sort By" class="md-no-underline">
                <md-option value="talkingAbout.projectedTA">Risk</md-option>
                <md-option value="talkingAbout.talkingAbout">Talk</md-option>
                <md-option value="name">Name</md-option>
                <md-option value="age">Age</md-option>
              </md-select>
            </md-input-container>

      </section>
    </div>
  </md-toolbar>

Here is how my ng-repeat is defined.

<div ng-repeat="d in data | filter:user.name | orderBy: sort track by d.name" flex>

The value for sort is set, when the option is selected, but does not reflect in the orderby.

AT82
  • 71,416
  • 24
  • 140
  • 167
SAS
  • 13
  • 6
  • if I had to guess, this is probably happening because `md-toolbar` or `md-input-container` (or both) is creating a child `$scope` behind the scenes. This is one of *many* examples of what should be a mantra when using Angular.js: **"Always use a dot in angular bindings."** – Claies Apr 30 '17 at 23:20
  • in other words, try creating an object in your controller to bind to, something like `page.sort` rather than just `sort`. – Claies Apr 30 '17 at 23:22
  • I was able to print the sort variable like {{sort}}, through out the page. So assume the same should apply under ng-repeat. Can you explain what you mean by use a dot in angular bindings? How can I tell if there are different instances of sort being referenced here? – SAS Apr 30 '17 at 23:23
  • in my controller I am initializing sort with $scope.sort = 'name'; – SAS Apr 30 '17 at 23:24
  • do you have a full [mcve], with sample data? – Claies Apr 30 '17 at 23:25
  • I do, I just read this: "Sample scenario: a parent scope with $scope.foo = "bar", and a child scope with a . It will display bar initially, but once the user changes the value, a foo will be created on the child scope and the binding will read and write that value. The parent's foo will remain bar. Hope that summarises it well." – SAS Apr 30 '17 at 23:27
  • this is the best answer on the subject, and deserves a thorough readthrough: http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs. it even includes pictures to illustrate the concepts. – Claies Apr 30 '17 at 23:29
  • Thank you, I will read through it, if not will sanitize the code and share.. – SAS Apr 30 '17 at 23:31
  • I read through and understand the logic and how it should work. Still not sure, how to use an object to assign and refer by sort value. – SAS Apr 30 '17 at 23:43
  • for ng-model, can I refer the variable something like "this.sort" ? ng-model = "this.sort" – SAS Apr 30 '17 at 23:45
  • not `this` (`this` is a reserved keyword) but you can create an object in the controller, something like `$scope.page` with a property `sort` (`$scope.page.sort`) instead of a primitive (`$scope.sort`). primitives are passed **byVal**, while objects are passed **byRef**, meaning that in a sub scope, you only see the initial value of primitives, not any changes to the primitive. – Claies Apr 30 '17 at 23:47
  • 1
    I think you have a problem in your JSON data structure, I can't reproduce your error. Check this [PLUNKER](https://plnkr.co/edit/P2P9kXfyFBr92DozTlui). You can update it and use it for your question. – The.Bear May 01 '17 at 00:32
  • Thank you @Claise. I had fixed the issue, but didn't update here. The issue, as predicted was due to the child scope being created that I was not intending. I was able to follow and fix the issue as described here: http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs – SAS May 04 '17 at 23:28
  • 1
    @The.Bear Thanks, your update explains my fix! – SAS May 04 '17 at 23:28

1 Answers1

0

var app = angular.module('stack', ['ngMaterial']);

app.controller('MainCtrl', function($scope) {
  $scope.data = [
    {
      name: "Manu",
      age: 39,
      talkingAbout: {
        risk: 1,
        talkingAbout: "Talk 2"
      }
    },
    {
      name: "Tony",
      age: 34,
      talkingAbout: {
        risk: 2,
        talkingAbout: "Talk 3"
      }
    },
    {
      name: "Patty",
      age: 30,
      talkingAbout: {
        risk: 3,
        talkingAbout: "Talk 1"
      }
    }
  ];
});
<!DOCTYPE html>
<html ng-app="stack">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Stack</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.1.4/angular-material.min.css" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular-animate.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular-aria.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular-messages.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.1.4/angular-material.min.js"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">

  <md-input-container>
    <md-select ng-model="sort" placeholder="Sort By" class="md-no-underline">
      <md-option value="talkingAbout.risk">Risk</md-option>
      <md-option value="talkingAbout.talkingAbout">Talk</md-option>
      <md-option value="name">Name</md-option>
      <md-option value="age">Age</md-option>
    </md-select>
  </md-input-container>
  
  <h4>Selected: {{sort}}</h4>

  <div ng-repeat="d in data | orderBy: sort track by d.name" flex>
    {{d.name + " - " + d.age + " - " + d.talkingAbout.risk + " - " + d.talkingAbout.talkingAbout}}
  </div>
</body>

</html>
Max Pringle
  • 621
  • 6
  • 18