JSRB
JSRB

Reputation: 2613

How can I add a new key:value pair to an existing Javascript object dynamically within a loop

I would like to calculate a new value based on two objects and add the result as new object to the existing array.

The input looks like:

[{
    "trades": [
        {
        "fields": {
                "orderOpenPrice": "1.40000",
                "orderTakeProfit": "1.50000",
                [...]

        },
        },

        {
          "fields": {
                "orderOpenPrice": "1.30000",
                "orderTargetPrice": "1.50000",
                [...]
        }
        },
        {
        "fields": {
                "orderOpenPrice": "1.50000",
                "orderTargetPrice": "1.55000",
                [...]
        }
        },

        [...]

}]

This is the desired output:

[{
    "trades": [
        {
        "fields": {
                "orderOpenPrice": "1.40000",
                "orderTakeProfit": "1.50000",
                "pipsTargetedKey": "10000",
                [...]

        },
        },

        {
          "fields": {
                "orderOpenPrice": "1.30000",
                "orderTakeProfit": "1.50000",
                "pipsTargetedKey": "20000",
                [...]
        }
        },
        {
        "fields": {
                "orderOpenPrice": "1.50000",
                "orderTakeProfit": "1.55000",
                "pipsTargetedKey": "5000",
                [...]
        }
        },

        [...]

}]

I tried two different approaches using this thread: How can I add a key/value pair to a JavaScript object?:

Using assign:

[...]
for (var i = 0; i < tradesTotal; i++) {
    pipsTargeted = Math.abs(trades[i].fields.orderOpenPrice - trades[i].fields.orderTakeProfit);
    trades[i].fields.assign(trades[i].fields, {pipsTargetedKey: pipsTargeted});
}
[...]


Using dot notation:

[...]
for (var i = 0; i < tradesTotal; i++) {
    pipsTargeted = Math.abs(trades[i].fields.orderOpenPrice - trades[i].fields.orderTakeProfit);
    trades[i].fields.pipsTargetedKey = pipsTargeted
}
[...]

However, both attempts do not add another key:value pair.

Edit on request:

tradesTotal = Object.keys(trades).length;

// manipulate trades object
for (var i = 0; i < tradesTotal; i++) {

    // format dateTime
    trades[i].fields.orderOpenTime = (trades[i].fields.orderOpenTime).replace('T', ' ');
    if (trades[i].fields.orderCloseTime !== null)
    trades[i].fields.orderCloseTime = (trades[i].fields.orderCloseTime).replace('T', ' ');

    // format orderType
    if (trades[i].fields.orderType === 0) {
        trades[i].fields.orderType = 'Buy'
    } else if (trades[i].fields.orderType === 1) {
        trades[i].fields.orderType = 'Sell'
    } else if (trades[i].fields.orderType === 2) {
        trades[i].fields.orderType = 'Buy Limit'
    } else if (trades[i].fields.orderType === 3) {
        trades[i].fields.orderType = 'Sell Limit'
    } else if (trades[i].fields.orderType === 4) {
        trades[i].fields.orderType = 'Buy Stop'
    } else if (trades[i].fields.orderType === 5) {
        trades[i].fields.orderType = 'Sell Stop'
    } else if (trades[i].fields.orderType === 6) {
        trades[i].fields.orderType = 'Bank Transaction'
    }

    // calculate R:R and TP + SL in pips and add result to object
    if (stopLoss && takeProfit > 0) {
        pipsRisked = Math.abs(trades[i].fields.orderOpenPrice - trades[i].fields.orderStopLoss);
        pipsTargeted = Math.abs(trades[i].fields.orderOpenPrice - trades[i].fields.orderTakeProfit);
        rrRatio = (pipsTargeted / pipsRisked);
        trades[i].fields.pipsRiskedKey = pipsRisked;
        trades[i].fields.pipsTargetedKey = pipsTargeted;
        trades[i].fields.pipsRRKey = rrRatio;
    }
}

Upvotes: 0

Views: 82

Answers (2)

Nick Parsons
Nick Parsons

Reputation: 50749

As you mentioned trades is an array. When you do Object.keys() on an array, you get the indexes of that array. This can be simplified to just trades.length as they are the same thing.

Currently, you're looping over trades, which allow you to access each object in your array. Each object has a trades property with an array, which you also need to loop over. This means you need a nested loop. One to loop over all your objects in your larger, and another to loop over all your objects in your trades property array. This can be done like so:

const tradesTotal = [{
  "trades": [{
      "fields": {
        "orderOpenPrice": "1.40000",
        "orderTakeProfit": "1.50000",


      },
    },

    {
      "fields": {
        "orderOpenPrice": "1.30000",
        "orderTargetPrice": "1.50000",

      }
    },
    {
      "fields": {
        "orderOpenPrice": "1.50000",
        "orderTargetPrice": "1.55000",

      }
    },
  ]
}];


for (var i = 0; i < tradesTotal.length; i++) {
  var trades = tradesTotal[i].trades;
  for (var j = 0; j < trades.length; j++) {
    var pipsTargeted = Math.abs(trades[j].fields.orderOpenPrice - trades[j].fields.orderTakeProfit);
    trades[j].fields.pipsTargetedKey = pipsTargeted
  }

}
console.log(tradesTotal);

Upvotes: 1

Evgeny Korzun
Evgeny Korzun

Reputation: 91

Just use Array.prototype.map function and spead operator:

const trades = [
  {
    "fields": {
      "orderOpenPrice": "1.40000",
      "orderTakeProfit": "1.50000",
    },
  },
  {
    "fields": {
      "orderOpenPrice": "1.30000",
      "orderTakeProfit": "1.50000",
    }
  },
  {
    "fields": {
      "orderOpenPrice": "1.50000",
      "orderTakeProfit": "1.55000",
    }
  }
]

const mappedTrades = trades.map(trade => {
  const {orderOpenPrice, orderTakeProfit} = trade.fields
  return {
     ...trade,
     fields: {
        ...trade.fields,
        pipsTargetedKey: Math.abs(Number(orderOpenPrice) - Number(orderTakeProfit))
     }
  }
})

Another way is to use something like Proxy or Object.observe.

Upvotes: 0

Related Questions