Editing JavaScript Object using AngularJS
At times we encounter a situation when we need to edit a JavaScript object(JSON). By editing, I mean modifying the keys and values of the object, or dynamically adding a new key and value to the object.
Well, to make such a situation more clear, let us see a scenario:
Suppose there are two input fields and a button:
- In the first input field, we need to add the key of the object.
- Second input field takes the value that would be added to the corresponding key(i.e. the first input field).
- On clicking the ‘Add’ button, pair of input fields would get added, which can then take the key-value pair.
Here is the HTML and JavaScript code for it:
editObject.html:
<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body ng-controller="ObjectController as objectController">
<h2>Key-Value:</h2>
<div ng-repeat="oldKey in objectController.notSorted(objectController.student)">
<label>Key </label>
<input type="text" ng-model="newKey" ng-init="newKey=oldKey" ng-blur="objectController.updateKey(newKey, oldKey)">
<label>Value </label>
<input type="text" ng-model="newValue" ng-init="newValue=objectController.student[oldKey]"
ng-blur="objectController.updateValue(newValue,oldKey)">
</div>
</br>
<em>Click on 'Add' to add another key-value pair.</em>
</br>
</br>
<input type="button" value="Add" ng-click="objectController.addNewKey()"/>
<h2>Object:</h2>
<script src="angular.min.js"></script>
<script src="ObjectController.js"></script>
</body>
</html>
ObjectController.js:
/**
* Created by Namita malik on 25/4/15.
*/
(function (ng) {
var myApp = ng.module('myApp', []);
myApp.controller('ObjectController', [function () {
var objectController = this;
objectController.student = {name: "Namita", age: "16", class: "XII", school: "BBPS"};
objectController.updateKey = function (newKey, oldKey) {
if (newKey == "") {
delete objectController.student[oldKey];
} else if (newKey !== oldKey) {
objectController.student[newKey] = objectController.student[oldKey];
delete objectController.student[oldKey];
}
};
objectController.updateValue = function (newValue, key) {
objectController.student[key] = newValue;
};
objectController.notSorted = function (object) {
return object ? Object.keys(object) : [];
};
objectController.addNewKey = function () {
objectController.student[""] = "";
};
}]);
})(angular);
Before starting with the actual logic in the above code, please note that the above code is written in controller as syntax. Here are a few points for that:
- I have created an alias
objectController
for my controllerObjectController
here<body ng-controller="ObjectController as objectController">
. - In the
Controller
, I have not passed $scope object to the function, instead created a variable namedobjectController
and assignedthis
to it. Instead of hanging around with $scope, I have added model data and the behaviour to the controller instance. - Instead of defining function with $scope, I have defined it on this (
objectController
). - Using controller as syntax is a personal choice, but I am finding it more readable and consistent and also I am getting rid of the
$scope
.
Let’s now come to the actual scope of this post, i.e. editing a JavaScript Object.
We have a student object whose keys and values are being displayed. We are modifying this student object.
If you look at the above demo, we can do two things there:
- Modify the existing keys/values.
- Add new key/value.
Here is explanation of both the cases:
####1 : Modify the existing keys/values.
- We have an
updateKey
function, which is called as soon as user modifies the key.updateKey()
is called on the blur event of the key field. updateKey()
takes two parameters i.e.newKey
andoldKey
, names of which are self explanatory.- Now, let’s move on to
HTML
for a while and see what is happening there. We need to investigate these two lines specifically:<div ng-repeat="oldKey in objectController.notSorted(objectController.student)">
and<input type="text" ng-model="newKey" ng-init="newKey=oldKey" ng-blur="objectController.updateKey(newKey, oldKey)">
. - We are iterating the object using the ng-repeat directive and hence we are using the
oldKey
, as an object can be iterated using the key. - There is an ng-model on the key field. This model has been bind to the
newKey
. We are initializing the value ofnewKey
with theoldKey
. - We know that blur event is fired when an element looses focus, so when a user ends updating the key and moves to the other field using keyboard or clicks anywhere,
updateKey
function would be called which would take bothnewKey
andoldKey
as its arguments. - Now, coming back to our
updateKey
function, we check that ifnewKey
is not equal tooldKey
, I pass the value in theoldKey
to thenewKey
and then delete theoldKey
using the delete operator. - In case user updates an existing key with an empty string, in that case, key would be deleted as empty key would not make sense.
- Now, let’s check the
updateValue
function. This function is called when the blur event is fired on the the value field. - On the
HTML
have a look at this code:<input type="text" ng-model="newValue" ng-init="newValue=objectController.student[oldKey]" ng-blur="objectController.updateValue(newValue,oldKey)">
. The input field for value has modelnewValue
. We initializenewValue
with the value in theoldKey
. Once user modifies the value and focus is lost,updateValue()
function is called which takesnewValue
andoldKey
along with it as its arguments. - Let’s see the definition part of
updateValue
function. In this function, we are simply passing the updated value(newValue
) to theoldKey
.
So this was all about updating key and value. Now let’s take up the second case:
####2. Add new key/value.
- On clicking the “Add” button,
addNewKey
function is called. - In the
addNewKey
function, we are simply adding an empty string as the key and assigning empty string as a value to it. Now, as soon as user enters a key in this newly added key field and the field looses the focus, ourupdateKey()
function would be called, which would then do all the magic explained above.