Issue with the object references in Angularjs - angularjs

I have a simple function below using which am trying create dynamic div containing a d3 chart for each row from the given input "json.res_full_sk"
However, when I use apply in Angularjs, am losing the historic data that is being assigned to dyndata object.
<script>
var app = angular.module('rpPlotExampleApp', ['ui.rpplot']);
app.controller('rpPlotCtrl', function ($scope) {
$scope.dyndata={};
$scope.assign_sk = function (testjsobj) {
alert('From Angular JS'+ JSON.stringify(testjsobj));
$scope.dyndata=testjsobj;
};
});
</script>
<script type="text/javascript">
jsonList = [];
jsonList.res_full_sk = [
{ "tid": 20, "sk": [{ "name": "Banking", "value": 40, "id": 0 }, { "name": "Housing", "value": 4, "id": 1 }, { "name": "Home", "value": 4, "id": 2 }, { "name": "NET", "value": 4, "id": 3 }] },
{ "tid": 22, "sk": [{ "name": "Movie", "value": 12, "id": 0 }, { "name": "Movie2", "value": 4, "id": 1 }, { "name": "Housing", "value": 4, "id": 2 }, { "name": "Banking", "value": 4, "id": 3 }, { "name": "C", "value": 4, "id": 4 }] },
{ "tid": 24, "sk": [{ "name": "Housing", "value": 4, "id": 0 }, { "name": "Home", "value": 4, "id": 1 }, { "name": "Banking", "value": 4, "id": 2 }] }
];
arr = [];
function getObjContents(i) {
arr = $.grep(jsonList.res_full_sk, function (e) {
return e.tid == i;
});
var str = "";
for (var i = 0; i < arr[0].sk.length; i++) {
str += ","+ JSON.stringify(arr[0].sk[i]);
}
str=str.substring(1);
str = "[" + str + "]";
str_obj=JSON.parse(str);
str_fin = {};
str_obj.forEach(function (e, i) {
str_fin['d' + i] = e;
});
return str_fin;
}
function insertDiv(Num) {
array = [];
var ar1 = Num.replace('[', '');
array = JSON.parse("[" + ar1 + "]");
var i = 0;
for (i; i < array.length; i++) {
js_data={};
js_data=getObjContents(array[i]);
testjsobj=js_data;
var scope = angular.element(document.getElementById("rpPlotCtrl")).scope();
scope.$watch("dyndata", function (oldval, newval) {
}, true);
scope.$apply(function () {
scope.dyndata = js_data;
});
var id_num;
id_num = array[i];
var rChart = angular.element(document.getElementById("sktemp"));
rChart.injector().invoke(function ($compile) {
$('<div obj></div>').insertAfter("#sktemp")
var obj = $('[obj]'); // get wrapper
var scope1 = $('[obj]').scope();
// generate dynamic content
alert(JSON.stringify(scope1.dyndata));
obj.html("<div class='skpro' id='skpro" + id_num + "' name='cn'><div class='skprovis' id='skprovis" + id_num + "' >Hello " + id_num + "<div class='half-plot' style='height:95%;width:95%;margin-top:0px;margin-left:5px;'><rp-plot dsn='dyndata' point-radius='1.5' scale='log' labelled='true' class='plot-rp-plot'></rp-plot></div></div></div>");
// compile!!!
console.log(obj.contents());
$compile(obj.contents())(scope1);
scope1.$apply();
});
}
}
</script>
The problem is dyndata is being changed for each value of i in the for loop, and thus the d3 chart is updated with the lastly assigned dyndata object.
As I see the dyndata object is being assigned with different values each time for loop executes, but it is not remaining but changes with the next value of dyndata to all the charts that were created.
How can I get the historic data to persist for dyndata that is already rendered for each for loop execution?
Am new to Angularjs and not very sure how I can make use of Angular.copy() for this scenario.
Problem seems to be with below code -
var scope = angular.element(document.getElementById("rpPlotCtrl")).scope();
scope.$watch("dyndata", function (oldval, newval) {
}, true);
scope.$apply(function () {
scope.dyndata = js_data;
});
as soon as I assign new js_data value to dyndata, all the existing charts gets updated with new value.
I tried using angular.copy(scope.dyndata)=js_data.. But it didn't work out.
Can you please suggest me?

Related

Conversion of list of JSON array to a single object in Angular

I have an array list which needs to be converted to a single object with few of the values from array list using TypeScript in Angular 8. Below is the array:
"arrayList": [{
"name": "Testname1",
"value": "abc"
},
{
"name": "Testname2",
"value": "xyz"
}
]
This needs to be converted to the below format,
data: {
"Testname1": "abc",
"Testname2": "xyz",
}
No matter how much i try, i end up creating a list instead of a single object. Can you please help on the same?
You can use as follows,
var arr = [
{
"name": "Testname1",
"value": "abc"
},
{
"name": "Testname2",
"value": "xyz"
}
];
var result = {};
for (var i = 0; i < arr.length; i++) {
result[arr[i].name] = arr[i].value;
}
console.log(result);
Try with using .reduce() as the following:
const arrayList = [{ "name": "Testname1", "value": "abc" }, { "name": "Testname2", "value": "xyz" }];
const data = arrayList.reduce((a, {name, value}) => {
a[name] = value;
return a;
}, {});
const result = { data };
console.log(result);
Use Array.map() to get a list of [name, value] entries, then use Object.fromEntries() to convert to an object:
const arrayList = [{ "name": "Testname1", "value": "abc" }, { "name": "Testname2", "value": "xyz" }];
const result = Object.fromEntries(arrayList.map(({ name, value }) => [name, value]));
console.log(result);
Please use the below code
const rawData = {
"arrayList": [{
"name": "Testname1",
"value": "abc"
},
{
"name": "Testname2",
"value": "xyz"
}
]
};
const updatedData = {
data: {}
};
for (const item of rawData["arrayList"]) {
updatedData.data[item.name] = item.value;
}
console.log(updatedData);

pushing values from json into array

JSON:
var res =
{
"response": {
"data": {
"profilesearchsnippet": [
[
{
"profileInfo": {
"firstname": "Sundar",
"lastname": "v",
"gender": "male",
"country": "Afghanistan",
"state": "Badakhshan",
"city": "Eshkashem",
"pincode": "",
"plancode": "T001",
"userid": 13
},
"roleInfo": {
"defaultphotoid": 94
}
}
],
[
{
"profileInfo": {
"firstname": "ghg",
"lastname": "vbhvh",
"gender": "male",
"state": "Badakhshan",
"city": "Eshkashem",
"pincode": "454",
"plancode": "T001",
"userid": 22
},
"roleInfo": {
"defaultphotoid": 171
}
}
]
]
}
}
}
In the above json , I need to move roleInfo.defaultphotoid into var image
JS:
$scope.setimage = res.response.data.profilesearchsnippet[0];
for (var i = 0; i++; i<setimage.length; i++){
var image = [];
image .push(setimage[i].roleinfo.defaultphotoid);
}
I assigned one variable named setimage and from there I am trying to push values of all defaultphotoid in another array image to fetch images of all roleinfos, but I am able to fetch only first value.
This is because var image = [] is inside the for loop. It gets re-initialized after every cycle. You need to put it outside the loop
$scope.setimage = res.response.data.profilesearchsnippet[0];
var image = [];
for (var i = 0; i<$scope.setimage.length; i++){
image.push($scope.setimage[i].roleinfo.defaultphotoid);
}
You could use angular.foreach inorder to iterate the elements and set into the variable.
var log = [];
angular.forEach(res.response.data.profilesearchsnippet[0], function(value, key) {
this.push(setimage[i].roleinfo.defaultphotoid);
}, log);
https://docs.angularjs.org/api/ng/function/angular.forEach
try this:
$scope.setimage = res.response.data.profilesearchsnippet;
var images = [];
for (var i = 0; i<$scope.setimage.length; i++){
image.push($scope.setimage[i][0].roleinfo.defaultphotoid);
}
will work.

Protractor test not executing

I have a protractor test. I want to provide some data for a test so i can generate tests automatically.
My function is as below. The problem is that i can console log something after the opening of describe. But this is'nt the case after the it function.
The code:
bigTestFunction = function(testElements) {
testElements = JSON.parse(testElements);
for (i = 0; i < testElements.length; i++) {
var title = testElements[i].title;
var shouldText = testElements[i].should
var url = testElements[i].url;
var actions = testElements[i].action;
describe(title, function() {
it(shouldText, function() {
goToUrl(url);
for (x = 0; x < actions.length; x++) {
var action = actions[x].action;
var value = actions[x].value;
var element = actions[x].element;
var notEmpty = actions[x].notEmpty;
var nested = actions[x].nested;
if (action === 'sendKeys') {
sendKey(element, value);
}
if (action === 'click') {
click(element, notEmpty);
if (nested) {
for (x = 0; x < nested.length; x++) {
if (nested[x]['action'] === 'sendKeys') {
sendKey(nested[x]['element'], nested[x]['value']);
}
if (nested[x]['action'] === 'click') {
click(nested[x]['element'], nested[x]['notEmpty']);
}
}
}
}
}
});
});
}
}
testElements = JSON.parse(testElements);
the json:
[
{
"id": 1,
"title": "Small test one",
"should": "should start training",
"url": "https://ledmagazine.nl/home",
"actions": [
{
"id": 1,
"test_id": 1,
"element": "/html/body/div[1]/div/div/header/div/div[2]/div[2]/div/div/div/div/nav/section/ul/li[3]/a",
"action": "click",
"status": "notEmpty",
"value": "/html/body/div[1]/div/div/div[2]/div/div/div[1]/div/section",
"nested": {
"id": 1,
"action_id": 1,
"action": "sendKeys",
"element": "//*[#id=\"mce-EMAIL\"]",
"value": "dennisageffen#hotmail.com",
"created_at": null,
"updated_at": null
}
}
]
}
]
I think i'm really close but the function stops after 'describe(title, function() {...'
Propably you are missing beforeEach(function() {...} to get data.

Angularjs Splice in Nested Array

Hi can somebody help Removing element from nested json array like this
JSON
[{
"id": 1,
"name": "Furniture & Fixture",
"choice": {
"0": {
"req_goods": "table",
"qty": "10"
},
"1": {
"req_goods": "chair",
"qty": "5"
}
}
}, {
"id": 2,
"name": "Miscellaneous Property",
"choice": {
"0": {
"req_goods": "Office Rent",
"qty": "1"
}
}
}]
here how do I remove choice 1 of id 1 .
HTML
<div ng-repeat="cb in capital_budgets">
<div ng-repeat="choice in choices[$index]">
<input ng-model="cb.choice[$index].req_goods">
<input ng-model="cb.choice[$index].qty">
<button ng-hide="$first" ng-click="removeChoice($parent.$index,$index)">-</button>
</div>
<button ng-click="addNewChoice($index)">+</button>
</div>
JS
$scope.capital_budgets = [{"id":1,"name":"Furniture & Fixture"},
{"id":2,"name":"Miscellaneous Property"}];
$scope.choices = [{}];
$scope.choices[0] = [{}];
$scope.choices[1] = [{}];
$scope.choices[2] = [{}];
$scope.choices[3] = [{}];
$scope.choices[4] = [{}];
$scope.addNewChoice = function(id) {
$scope.choices[id].push({});
};
$scope.removeChoice = function(parent_id, id) {
$scope.choices[parent_id].splice(id, 1);
};
The Above removeChoice() remove last element but I want to remove the element that user choose to remove. please help i have been trying from 2 days.
You can make 'choice' of the array type as follows and use the index of the particular choice in the ng-repeat directive to remove the choice from the choices array.
angular
.module('demo', [])
.controller('DefaultController', DefaultController);
function DefaultController() {
var vm = this;
vm.items = [
{
"id": 1,
"name": "Furniture & Fixture",
"choices": [
{
"id": 1,
"req_goods": "table",
"qty": "10"
},
{
"id": 2,
"req_goods": "chair",
"qty": "5"
}]
}, {
"id": 2,
"name": "Miscellaneous Property",
"choices": [
{
"id": 1,
"req_goods": "Office Rent",
"qty": "1"
}]
}];
vm.removeChoice = removeChoice;
vm.addChoice = addChoice;
function removeChoice(itemId, index) {
for (var i = 0; i < vm.items.length; i++) {
if (vm.items[i].id === itemId) {
vm.items[i].choices.splice(index, 1);
break;
}
}
}
function addChoice(index) {
var id = vm.items[index].choices.length + 1;
vm.items[index].choices.push({
id: id,
req_goods: "",
qty: 0
});
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demo">
<div ng-controller="DefaultController as ctrl">
<div ng-repeat="item in ctrl.items">
<h3>{{item.name}}</h3>
<div ng-repeat="choice in item.choices">
<input type="text" ng-model="choice.req_goods" />
<input type="text" ng-model="choice.qty" />
<button type="button" ng-click="ctrl.removeChoice(item.id, $index)">Remove</button>
</div>
<button type="button" ng-click="ctrl.addChoice($index)">Add</button>
</div>
</div>
</div>
You can remove choice "1" of id 1 using the below code snippet.
var json = [
{
"id": 1,
"name": "Furniture & Fixture",
"choice": {
"0": {
"req_goods": "table",
"qty": "10"
},
"1": {
"req_goods": "chair",
"qty": "5"
}
}
}, {
"id": 2,
"name": "Miscellaneous Property",
"choice": {
"0": {
"req_goods": "Office Rent",
"qty": "1"
}
}
}];
function removeChoice(json, parentId, choice) {
for (var i = 0; i < json.length; i++) {
if (json[i].id === parentId) {
delete json[i].choice[choice];
break;
}
}
}
removeChoice(json, 1, "1");
console.log(json);
If you want the the choice also to be of the same type as its parent element i.e. an array you could change your JSON as follows and do as shown in the below code snippet to remove a choice from the JSON
var json = [
{
"id": 1,
"name": "Furniture & Fixture",
"choices": [
{
"id": 1,
"req_goods": "table",
"qty": "10"
},
{
"id": 2,
"req_goods": "chair",
"qty": "5"
}]
}, {
"id": 2,
"name": "Miscellaneous Property",
"choices": [
{
"id": 1,
"req_goods": "Office Rent",
"qty": "1"
}]
}];
function removeChoice(json, parentId, choiceId) {
for (var i = 0; i < json.length; i++) {
if (json[i].id === parentId) {
for (var j = 0; j < json[i].choices.length; j++) {
if (json[i].choices[j].id === choiceId) {
json[i].choices.splice(j, 1);
break;
}
}
break;
}
}
}
removeChoice(json, 1, 1);
console.log(json);
In both of the above methods I've passed the source you want to modify as a parameter to the removeChoice function whereas you can also directly use a variable available within the scope of execution of the removeChoice function and pass only parentId and choiceId as parameters in the below code snippet, you can replace items with the object on your controller's $scope.If you prefer isolation of the code you can pass the items object as a parameter to the removeChoice function as it won't be dependent on the external components directly being used in the method body, I would suggest to have separation of concerns.
var items = [
{
"id": 1,
"name": "Furniture & Fixture",
"choices": [
{
"id": 1,
"req_goods": "table",
"qty": "10"
},
{
"id": 2,
"req_goods": "chair",
"qty": "5"
}]
}, {
"id": 2,
"name": "Miscellaneous Property",
"choices": [
{
"id": 1,
"req_goods": "Office Rent",
"qty": "1"
}]
}];
function removeChoice(parentId, choiceId) {
for (var i = 0; i < items.length; i++) {
if (items[i].id === parentId) {
for (var j = 0; j < items[i].choices.length; j++) {
if (items[i].choices[j].id === choiceId) {
items[i].choices.splice(j, 1);
break;
}
}
break;
}
}
}
removeChoice(1, 1);
console.log(items);
Try This
$scope.removeChoice = function(parent_id,id) {
var TempArr=[];
var parentLength=$scope.choices[parent_id].length;
for(i=0;i<parentLength;i++ ){
if(parentLength[i]!==id){
TempArr.push(parentLength[i]);
}
if(i==parentLength-1){
$scope.choices[parent_id]=[];
$scope.choices[parent_id]=TempArr;
}
}
};

AngularJs filter is not working correctly

Please see the link
http://plnkr.co/edit/Cn0sNDGEkPOzV19ye8NW?p=preview
I have changed my JSON, then I can't able to filter the data.
var result = $filter('filter')(foo.results, {id:2426})[0];
if you limit on your JSON data
and you can make sure the data property value is num
maybe you can try this ...
var foo = {
"count": 70,
"language": "en",
"0": {
"id": "2420",
"name": "Medical Center"
},
"1": {
"id": "7840",
"name": "Conference Room"
},
"2": {
"id": "2426",
"name": "Deck 5 Starboard"
}
};
foo.results = [];
for(var property in foo){
if(property == parseInt(property, 10).toString()){
foo.results.push(foo[property]);
}
}
var result = $filter('filter')(foo.results, {id:2426})[0];
$scope.name = result.name;
wish help !!

Resources