title: Angular 2 sorting with lodash
body: <p>Component:</p>
  
  <pre><code>import { Component, OnInit } from '@angular/core';
  import { HttpClient } from '@angular/common/http';
  import * as _ from 'lodash';
  
  @Component({
    selector: 'app-ore-table',
    templateUrl: './ore-table.component.html',
    styleUrls: ['./ore-table.component.less']
  })
  export class OreTableComponent implements OnInit {
    ores = '../assets/json/ores.json';
    prices = 'https://esi.tech.ccp.is/latest/markets/prices/?datasource=tranquility';
  
    oreArray: any;
    pricesArray: any;
    joinedArray: Array&lt;any&gt; = [];
    completeArray: Array&lt;any&gt; = [];
  
    seconds: number;
    turrets: any;
    turretYield: any;
    duration: any;
  
    constructor(private http: HttpClient) {
      this.seconds = 3600;
      this.turrets = 2;
      this.turretYield = 1593;
      this.duration = 106.9;
    }
  
    getOres() {
      this.http.get(this.ores).subscribe(data =&gt; {
        this.oreArray = data;
        this.getPrices();
      });
    }
  
    getPrices() {
      this.http.get(this.prices).subscribe(data =&gt; {
        this.pricesArray = data;
        this.joinPrices();
      });
    }
  
    joinPrices() {
      const cycles = this.seconds / this.duration;
      const totalYield = this.turretYield * this.turrets;
  
      this.oreArray.forEach((data) =&gt; {
        const matchingPrice = this.getMatchingPrice(data);
  
        const oreMined = totalYield * (1 / data.volume) * cycles;
        const hourIncome = matchingPrice.average_price.toFixed(2) * oreMined;
        const hourIncomeFormat = Number(hourIncome).toFixed();
        const isk = String(hourIncomeFormat).replace(/(.)(?=(\d{3})+$)/g, '$1,');
  
        if (matchingPrice !== false) {
            this.joinedArray.push({
                id: data.id,
                name: data.name,
                type: data.type,
                volume: data.volume.toFixed(2),
                average_price: matchingPrice.average_price.toFixed(2),
                max_income: isk,
                image: data.image
            });
        }
      });
      console.log(this.joinedArray);
      this.completeArray = _.sortBy(this.joinedArray, ['max_income']).reverse();
    }
  
    updatePrices(newTurrets, newTurretYield, newDuration) {
      console.log(newTurrets);
      this.joinedArray = [];
  
      const cycles = this.seconds / newDuration;
      const totalYield = newTurretYield * newTurrets;
  
      this.oreArray.forEach((data) =&gt; {
        const matchingPrice = this.getMatchingPrice(data);
  
        const oreMined = totalYield * (1 / data.volume) * cycles;
        const hourIncome = matchingPrice.average_price.toFixed(2) * oreMined;
        const hourIncomeFormat = Number(hourIncome).toFixed();
        const isk = String(hourIncomeFormat).replace(/(.)(?=(\d{3})+$)/g, '$1,');
  
        if (matchingPrice !== false) {
            this.joinedArray.push({
                id: data.id,
                name: data.name,
                type: data.type,
                volume: data.volume.toFixed(2),
                average_price: matchingPrice.average_price.toFixed(2),
                max_income: isk,
                image: data.image
            });
        }
      });
    }
  
    getMatchingPrice(data) {
      for (let i = 0; i &lt; this.pricesArray.length; i++) {
        if (this.pricesArray[i].type_id === data.id) {
              return this.pricesArray[i];
          }
      }
      return false;
    }
  
    ngOnInit() {
      this.getOres();
    }
  }
  </code></pre>
  
  <p>HTML:</p>
  
  <pre><code>&lt;tr *ngFor="let ore of completeArray" id="{{ ore.id }}"&gt;
          &lt;td&gt;&lt;img src="{{ ore.image }}" alt="{{ ore.name}}" /&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;{{ ore.name }}&lt;/strong&gt;&lt;/td&gt;
          &lt;td class="right aligned"&gt;{{ ore.volume }} m&amp;#179;&lt;/td&gt;
          &lt;td class="right aligned"&gt;{{ ore.average_price }} ISK&lt;/td&gt;
          &lt;td class="right aligned"&gt;{{ ore.max_income }}&lt;/td&gt;
        &lt;/tr&gt;
  </code></pre>
  
  <p>Screenshot:</p>
  
  <p><a href="https://i.stack.imgur.com/H6ISp.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/H6ISp.png" alt="enter image description here"></a></p>
  
  <p>I'm using lodash to sort my array by the <code>'max_income'</code> field and then applying <code>.reverse()</code> to sort it in descending order:</p>
  
  <pre><code>this.completeArray = _.sortBy(this.joinedArray, ['max_income']).reverse();
  </code></pre>
  
  <p>As seen in the screenshot above, it works perfectly other than the first row.  Because it starts with an 8, it's appearing first and this is completely wrong.  What adjustment can I make to force the numbers to sort properly?  Here as what an object looks like:</p>
  
  <pre><code>{
      "id": 17870,
      "name": "Vitreous Mercoxit",
      "type": "Mercoxit",
      "volume": "40.00",
      "average_price": "19000.04",
      "max_income": "50,964,186",
      "image": "../assets/images/Mercoxit.png"
    }
  </code></pre>