0

I found some possible solutions on this site but none of them really helped me forward.

My array looks like this:

[
  {"customerName":"Atelier graphique","addressLine1":"54, rue Royale"},
  {"customerName":"Signal Gift Stores","addressLine1":"8489 Strong St."},
  etc, etc

I want to change the customerName to value and addressLine1 to data. I tried the following but I am doing something wrong here.

var myArray = [];

$(document).ready(function () {
    $("#text-id").on( 'click', function () {
        $.ajax({
            type: 'post',
            url: 'connect.php',

            success: function( data ) {
                console.log( data );
                myArray.push(data);

        }
    });
});


function DumpCustomers() {

    for(i=0;i<myArray.length; i++){
        myArray[i].addressLine1= "data";
        delete myArray[i].addressLine1;
        myArray[i].customerName= "value";
        delete myArray[i].customerName;
    }

    alert(myArray);

}
shevski
  • 1,012
  • 1
  • 10
  • 32
Paul2503
  • 23
  • 4
  • 3
    who is calling `DumpCustomers` - have a look at http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call – Arun P Johny Sep 08 '14 at 12:53

3 Answers3

6

Just use Array.map to project your array values to the desired type:

var myTransformedArray = myOriginalArray.map(function(item){
    return {
       value : item.customerName,
       data : item.addressLine1
    };
});

If you need to support old browsers, you may need to add a polyfill to patch over the absence of a map function. The link above supplies this ECMA-262 5th Edition compliant implementation:

if (!Array.prototype.map) {
  Array.prototype.map = function(callback, thisArg) {
    var T, A, k;
    if (this == null) {
      throw new TypeError(" this is null or not defined");
    }
    var O = Object(this);
    var len = O.length >>> 0;
    if (typeof callback !== "function") {
      throw new TypeError(callback + " is not a function");
    }
    if (arguments.length > 1) {
      T = thisArg;
    }
    A = new Array(len);
    k = 0;
    while (k < len) {
      var kValue, mappedValue;
      if (k in O) {
        kValue = O[k];
        mappedValue = callback.call(T, kValue, k, O);
        A[k] = mappedValue;
      }
      k++;
    }
    return A;
  };
}
spender
  • 117,338
  • 33
  • 229
  • 351
  • This won't work in older browsers. Since OP is already using jQuery, consider [jQuery's `map`](http://api.jquery.com/jquery.map/) to support < IE 9: `$.map(myOriginalArray, function(item) { ....... })` – Shai Sep 08 '14 at 13:00
  • this ``map`` is not of jquery?? – Ehsan Sajjad Sep 08 '14 at 13:02
  • @EhsanSajjad: No, the one being used by spender's answer is ES5's `Array#map`. – T.J. Crowder Sep 08 '14 at 13:02
  • @Shai That won't work without jQuery. It's a huge patch to a very small problem. Better to use the Array.map polyfill in the link provided in my answer. https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Polyfill – spender Sep 08 '14 at 13:02
  • @spender In a project without jQuery I'd definitely recommend the polyfill. I'm glad you included it for people who read your answer in future. But the OP is already using jQuery – wouldn't including that polyfill be unnecessary code duplication? – Shai Sep 08 '14 at 13:07
  • @Shai : yes, I see your point. I tend to prefer the shim because it reduces dependencies which is always a good thing, especially if you ever reuse code. – spender Sep 08 '14 at 13:13
  • @EhsanSajjad: They're different functions. One, `Array#map`, is defined by ES5 and provided by all modern JavaScript engines. The other, `$.map`, is a jQuery function. They do similar things, but they're completely separate functions. – T.J. Crowder Sep 09 '14 at 04:24
0

You weren't that far off, but ask yourself, what does this line do:

myArray[i].addressLine1= "data";

? Right — it sets the value of the myArray[i].addressLine1 property to "data". That's not what you want. :-) You want to add a new property called data to myArray[i] and give it the value currently in myArray[i].addressLine1. You do that by assigning to the new property name:

myArray[i].data = myArray[i].addressLine1;

E.g.:

function DumpCustomers() {
    var i;

    for(i=0;i<myArray.length; i++){
        myArray[i].data = myArray[i].addressLine1;  // Change here
        delete myArray[i].addressLine1;
        myArray[i].value = myArray[i].customerName; // And here
        delete myArray[i].customerName;
    }

    alert(myArray);

}

...and at some point, you'll need to have code calling DumpCustomers, or move the part changing the property names into your success handler instead.

Note that I added var i at the top. Your code was falling prey to The Horror of Implicit Globals without it.

That said, if these are the only two properties in the array entries, I'd probably go with map per spender's answer, or do something like your loop but completely replacing the entries rather than modifying them:

function DumpCustomers() {
    var i;

    for(i=0;i<myArray.length; i++){
        myArray[i] = {
            data: myArray[i].addressLine1,
            value: myArray[i].customerName
        };
    }

    alert(myArray);

}
Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

Try to make a new Array :)

Like this:

var myArray = [
  {"customerName":"Atelier graphique","addressLine1":"54, rue Royale"},
  {"customerName":"Signal Gift Stores","addressLine1":"8489 Strong St."}
],

newArray = [];
for(var i = 0, len = myArray.length; i < len; i++)
{
    newArray.push({'value': myArray[i]['customerName'], 'data': myArray[i]['addressLine1']});
}

myArray = newArray;