1

I have an HTTP request in Angular that pulls all data from a Mysql table.

$http({
  method: "POST",
  url: "framework/actions/league.php?query=getDivision"
}).success(function(data){
  $scope.division = data;
});

A snippet of the data looks like this:

[
  {
    name: "Someone",
    number: "4",
    game1: "6",
    game2: "2",
    score: "8"
  },
  {
    name: "Someone else",
    number: "7",
    game1: "7",
    game2: "3",
    score: "10"
  },
]

When that data comes back from the HTTP request and gets assigned to $scope.division, the numbers are treated as strings, which gives me problems when using orderBy in an ngRepeat.

How can I get number fields to be treated as numbers without having to declare each field in a forEach and use parseInt()? Is it possible to do this in the PHP? If not, doing it in the Angular javascript would be fine.

Of course I can't treat every field as a number because of the name field.

CaribouCode
  • 13,998
  • 28
  • 102
  • 174
  • 1
    A *string* gets passed through the HTTP request, so you'll have to convert. – Jay Blanchard Oct 17 '14 at 12:45
  • Do you generate the JSON on your own server? May be easier to cast from (string) to (int) on the server rather than on the client. – ItalyPaleAle Oct 17 '14 at 12:47
  • 3
    I think the best resolution is that your server deliver correct format for your number. – Mathieu Bertin Oct 17 '14 at 12:47
  • @Qualcuno yes I have total control of the table and PHP. How do I cast as a number? – CaribouCode Oct 17 '14 at 12:49
  • @Coop just don't wrap it in quotes. – Nick Larsen Oct 17 '14 at 12:49
  • @Coop $integer = (int)$string http://php.net/manual/en/language.types.type-juggling.php – ItalyPaleAle Oct 17 '14 at 12:51
  • What format is the MySQL data column? – JAAulde Oct 17 '14 at 12:53
  • @JAAulde the format of all the number fields in the mysql table is int. Must be something along the process that is converting them. Either when the data is fetched, or the json_encode I do to send back to the javascript. – CaribouCode Oct 17 '14 at 12:55
  • @JAAulde it's actually normal: http://stackoverflow.com/questions/5323146/mysql-integer-field-is-returned-as-string-in-php – ItalyPaleAle Oct 17 '14 at 12:55
  • It is completely absurd that this is how PHP and MySQL interoperate. I don't know which end the problem lies on, but it should be straightened out ASAP. MySQL is a data store with data types--basically a serialization. There is no excuse to act as if everything coming from a DB is a string. Manual type casting is a massive waste of time and effort for all developers who are stuck using the nonsense that is PHP. – JAAulde Oct 17 '14 at 13:05
  • If you short the result from the very beginning when you make the query it would be a more accurate result in the browser. Otherwise you can only order the chunk you have on the client side. (chunk = 50 to 100 out of 5000 results) – Endless Oct 17 '14 at 13:50

1 Answers1

2

You can either convert the strings into numbers using the PHP function intval() before sending the result:

$string = '123';
$number = intval($string);
// 123

$number2 = intval('456');
// 456

Or casting the variable directly on an assign statement:

$string = '123';
$number = (int)$string;
// 123

$number2 = (int)'456';
// 456

Or do it in AngularJS using the transformResponse method:

$http({
    method: "POST",
    url: "framework/actions/league.php?query=getDivision",
    transformResponse: function(data) {

        for (var i=0; i<data.length; i++) {
            for(var k in data[i]) {
                if (data[i].hasOwnProperty(k)) {
                    data[i][k] = isNaN(+data[i][k]) ? data[i][k] : +data[i][k];
                }
            }
        }

        return data;   
    },
    success: function(data){
        $scope.division = data;
    }
});
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
  • Doing (int)$string is faster than calling intval(), by the way. (Also because there isn't the overhead of calling a function) – ItalyPaleAle Oct 17 '14 at 12:53
  • 1
    Your answer is actually true, but it is pretty much noticeable that you wrote it ASAP and you didn't maximize the power of AngularJS here (EVEN, you wrote a bad practice in angular, which can lead into confusing inconsistency on parts of code) . Declaring a service on $http request that will transformResponse is rather more suitable than creating custom data changes on $http.success function. – Linial Oct 17 '14 at 13:06
  • 1
    +1 for @linial. but also a plus to Marco for casting the variable directly on PHP side. If it is a number it should be treated as such and not as a string – Endless Oct 17 '14 at 13:10
  • @Linial you're right, I edited my answer, that's better. – Marco Bonelli Oct 17 '14 at 13:14
  • @Endless you are even more right. In this particular case there is not a real need for Client side manipulation. I'm just trying to get the best results for each question, It kinda suck if everyone end up writing code from SO which is completely tailor made to the issue, right? – Linial Oct 17 '14 at 13:17
  • 1
    @Linial Yes. But this answer is now very good. It shows the best of both worlds. (if you don't have access to the backend...) – Endless Oct 17 '14 at 13:22
  • I agree a front-end solution was not the way to go, so I ended up using the backend casting solution which worked great. I think by the time the data gets to the front end, it should be in the correct datatype. – CaribouCode Oct 17 '14 at 13:47