i am having a dynamic json data & 3 buttons "feed data" it contains one set of dynamic data and button 2 " feed another data" it contains another set of dynamic data and button 3 is " Send data" here my issue when ever i press feed data and select option and press send data it is working and after that if i press feed another data and press send data then it is giving error"isSelected is undefined"
error simulation : feed data --> select option --> send data & press feed another data --> select options --> send data then we are getting error
options = {
useCheckbox: true
};
arrayData;
nodes;
data = {
"info": {
"laptop": {
},
"config": {
"properties": {
"ram": {
},
"processor": {
},
"hdd": {
}
}
},
"link": {
},
"name": {
},
"company": {
"properties": {
"model": {
},
"maker": {
"type": "integer"
},
"country": {
"type": "text"
},
"enterprise": {
}
}
}
}
};
dataa = {
"info": {
"mobile": {
},
"config": {
"properties": {
"ram": {
},
"processor": {
},
"storage": {
}
}
},
"link": {
},
"name": {
},
"company": {
"properties": {
"model": {
},
"maker": {
"type": "integer"
},
"country": {
"type": "text"
},
"enterprise": {
}
}
}
}
};
click(tree:TreeModel)
{
this.arrayData= [];
console.log(tree.activeNodes);
let result: any = {};
let rs = [];
// tree.selectedLeafNodeIds = {};
Object.keys(tree.selectedLeafNodeIds).forEach(x=>{
let node:TreeNode=tree.getNodeById(x);
if (node.isSelected)
{
if (node.parent.data.name) //if the node has parent
{
rs.push(node.parent.data.name+'.'+node.data.name);
if (!result[node.parent.data.name]) //If the parent is not in the object
result[node.parent.data.name] = {} //create
result[node.parent.data.name][node.data.name] = true;
}
else {
if (!result[node.data.name]) //If the node is not in the object
result[node.data.name] = {} //create
rs.push(node.data.name);
}
}
})
this.arrayData = rs;
}
feedData(){
const results = Object.keys(this.data.info).map(k => ({
name: k,
children: this.data.info[k].properties
? Object.keys(this.data.info[k].properties).map(kk => ({name: kk}))
: []
}));
this.nodes = results;
}
feedAnother(){
const results = Object.keys(this.dataa.info).map(k => ({
name: k,
children: this.dataa.info[k].properties
? Object.keys(this.dataa.info[k].properties).map(kk => ({name: kk}))
: []
}));
this.nodes = results;
}
when ever i press feed data and press send data then i am able to view the info and lie wise i want to update data i press feed another data then press send data then it needs to get the updated results
below is my stack blitz url : https://stackblitz.com/edit/angular-zapxko
You can simply change nodes object to update the result.
You need to use Async Data method to update nodes. Here are the demo and code from Angular Tree's official documentation.
Related
I'm recieving a payload from SlackAPI (block elements) and I can't get my head around oh how do I get data from it as ids and order always change.
I want to get protection_fee.value, legal_fee.value and repayment_date.selected_date
"state": {
"values": {
"CjV": {
"protection_fee": {
"type": "plain_text_input",
"value": "111"
}
},
"36tAM": {
"legal_fee": {
"type": "plain_text_input",
"value": "111"
}
},
"oH8": {
"repayment_date": {
"type": "datepicker",
"selected_date": "1990-04-18"
}
}
}
},
I tried Object.keys but obviously I failed as order changes.
current code:
const payload = JSON.parse(body);
const state = payload.state.values;
const first = Object.keys(state)[0];
const second = Object.keys(state)[1];
const repaymentDate = state[first].protection_fee.value;
const protectionFee = state[second].legal_fee.value;
I would suggest creating a function like findProperty() that will find the relevant object in the payload.
We'd call Object.entries() on the payload.state.values object and then using Array.find() on the entry key/value pairs to find an object with the desired property.
Once we have the property we can return it.
let payload = { "state": { "values": { "CjV": { "protection_fee": { "type": "plain_text_input", "value": "111" } }, "36tAM": { "legal_fee": { "type": "plain_text_input", "value": "111" } }, "oH8": { "repayment_date": { "type": "datepicker", "selected_date": "1990-04-18" } } } } }
function findProperty(obj, key) {
const [, value] = Object.entries(obj).find(([k,v]) => v[key]);
return value[key];
}
console.log('legal_fee:', findProperty(payload.state.values, 'legal_fee').value)
console.log('protection_fee:', findProperty(payload.state.values, 'protection_fee').value)
.as-console-wrapper { max-height: 100% !important; }
I'm trying to use paularmstrong/normalizr on JSON that comes from FractalTransformer and whose nested childs have "data" attribute. Example of JSON:
{
"data": {
"object": "Offer",
"id": "5g6aqocew4qjzl40",
"real_id": 26,
"name": "Random Name",
"created_at": {
"date": "2019-06-18 11:13:08.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"readable_created_at": "1 year ago",
"site": {
"data": {
"object": "Site",
"id": "65zody8vj29vlegd",
"name": "Test Site",
"real_id": 1
}
},
"countries": {
"data": [
{
"object": "Country",
"code": "US",
"name": "United States"
},
{
"object": "Country",
"code": "DE",
"name": "Germany"
}
]
}
},
"meta": {
"include": [
"site",
"countries"
],
"custom": []
}
}
Schemas I use:
export const offerSchema = new schema.Entity('offers')
export const siteSchema = new schema.Entity('sites', {}, {
processStrategy: (value) => {
return { ...value.data }
},
idAttribute: (value) => {
return value.data.id
},
})
export const countrySchema = new schema.Entity('countries')
offerSchema.define({
site: siteSchema,
countries: [countrySchema],
})
Now the issue is that I remove 'data' from the site since it's just one object successfully, but I can't do it in the country case. Whatever I tried with custom processStrategy fails, as country is object that has data which is array (I assume this is where the issue is, going from Entity to Array). And in idAttribute function I always get complete array so can't determine the ID of single entry. So the end result is that the ID of countries is undefined. Any ides?
I actually managed with another approach. I added processStrategy on the parent, 'Offer' in this case, so all 'data' parts get stripped before they reach other child schemas.
const normalizrStripDataOptions = {
processStrategy: (value) => {
const ret = { ...value }
Object.keys(ret).forEach((key) => {
if (ret[key] !== null) {
if (ret[key].data && Array.isArray(ret[key].data)) {
ret[key] = [...ret[key].data]
}
if (ret[key].data && typeof ret[key].data === 'object') {
ret[key] = { ...ret[key].data }
}
}
})
return ret
},
}
export const offerSchema = new schema.Entity('offers', {}, normalizrStripDataOptions)
export const siteSchema = new schema.Entity('sites')
export const countrySchema = new schema.Entity('countries')
offerSchema.define({
site: siteSchema,
countries: [countrySchema],
})
I have a JSON Structure something like:
[
{
"name":"angelinas"
},
{
"name":"besuto"
},
{
"name":"catch",
"cuisine":"Japanese"
},
{
"name":"center cut"
},
{
"name":"fedora"
},
{
"name":"Habanero",
"cuisine":"Mexican"
},
{
"name":"Indies"
},
{
"name":"new"
},
{
"name":"RazINN"
},
{
"name":"restaurantTestVenue779"
},
{
"name":"restaurantTestVenue9703"
},
{
"name":"Salsa ",
"cuisine":"Mexican"
},
{
"name":"Sushi Place",
"cuisine":"Japanese"
},
{
"name":"The Ashoka"
},
{
"name":"The Poboys"
},
{
"name":"the shogun"
},
{
"name":"vinyard view"
}
]
Using the JSON above i want to identify whether a cuisine is assosiated to restaurant. If yes, I want to build a JSON Structure something like:
[
{
"Mexican":{
"venueNames":[
"Habanero",
"Salsa"
]
}
},
{
"Japanese":{
"venueNames":[
"Sushi Place",
"catch"
]
}
}
]
Have tried to build the JSON using a for loop and .hasProperty but not much of a success.
Here is what you can do!
First iterate through the data and use the method "hasOwnProperty" to check if the cuisine exists and if it does then check if your cuisines object has that cuisine and if does then add it to it.
const data = [{
"name": "angelinas"
},
{
"name": "besuto"
},
{
"name": "catch",
"cuisine": "Japanese"
},
{
"name": "center cut"
},
{
"name": "fedora"
},
{
"name": "Habanero",
"cuisine": "Mexican"
},
{
"name": "Indies"
},
{
"name": "new"
},
{
"name": "RazINN"
},
{
"name": "restaurantTestVenue779"
},
{
"name": "restaurantTestVenue9703"
},
{
"name": "Salsa ",
"cuisine": "Mexican"
},
{
"name": "Sushi Place",
"cuisine": "Japanese"
},
{
"name": "The Ashoka"
},
{
"name": "The Poboys"
},
{
"name": "the shogun"
},
{
"name": "vinyard view"
}
]
let cuisines = {};
for (const resturant of data) {
if (resturant.hasOwnProperty('cuisine')) {
if (cuisines.hasOwnProperty(resturant.cuisine)) {
cuisines[resturant.cuisine].venueNames.push(resturant.name);
} else {
cuisines[resturant.cuisine] = {
venueNames: [resturant.name]
};
}
}
}
You can use in one loop below.
data.forEach(function(item) {
// if item has cuisine and cuisine not exist in new array
if(item["cuisine"] != null && typeof newArr.find(v => v[item.cuisine] != null) == 'undefined') {
// create new object with structure
let obj = {};
obj[item.cuisine] = {
"venueNames":[item.name]
};
newArr.push(obj);
}
else {
// else find existing cuisine and add new venue
let obj = newArr.find(v => v.hasOwnProperty(item.cuisine));
if(typeof obj != 'undefined') {
obj[item.cuisine].venueNames.push(item.name);
}
}
});
JSFIDDLE
It's a simple reduction of the array. If the restaurant has a defined cuisine, check if the result already has this cuisine defined. If not, create an object for it where you can push the restaurant name to.
const restaurants = [
{
"name":"angelinas"
},
{
"name":"besuto"
},
{
"name":"catch",
"cuisine":"Japanese"
},
{
"name":"center cut"
},
{
"name":"fedora"
},
{
"name":"Habanero",
"cuisine":"Mexican"
},
{
"name":"Indies"
},
{
"name":"new"
},
{
"name":"RazINN"
},
{
"name":"restaurantTestVenue779"
},
{
"name":"restaurantTestVenue9703"
},
{
"name":"Salsa ",
"cuisine":"Mexican"
},
{
"name":"Sushi Place",
"cuisine":"Japanese"
},
{
"name":"The Ashoka"
},
{
"name":"The Poboys"
},
{
"name":"the shogun"
},
{
"name":"vinyard view"
}
];
const cuisines = restaurants.reduce((result, restaurant ) => {
if ( restaurant.hasOwnProperty( 'cuisine' )) {
const { cuisine } = restaurant;
if ( !result.hasOwnProperty( cuisine )) {
result[ cuisine ] = {
venueNames: []
};
}
result[ cuisine ].venueNames.push( restaurant.name );
}
return result;
}, {});
console.log( cuisines );
In my personal opinion, I would use a slightly different structure though. If we represent collections with objects that are always the same, we can simplify most transformations. This is less efficient that doing everything in one loop, but the code used to create the transformation is almost readable english:
const restaurants = [
{ "name": "angelinas", "cuisine": null },
{ "name": "besuto", "cuisine": null },
{ "name": "catch", "cuisine": "japanese" },
{ "name": "center cut", "cuisine": null },
{ "name": "fedora", "cuisine": null },
{ "name": "habanero", "cuisine": "mexican" },
{ "name": "Indies", "cuisine": null },
{ "name": "new", "cuisine": null },
{ "name": "RazINN", "cuisine": null },
{ "name": "restaurantTestVenue779", "cuisine": null },
{ "name": "restaurantTestVenue9703", "cuisine": null },
{ "name": "Salsa ", "cuisine": "mexican" },
{ "name": "Sushi Place", "cuisine": "japanese" },
{ "name": "The Ashoka", "cuisine": null },
{ "name": "The Poboys", "cuisine": null },
{ "name": "the shogun", "cuisine": null },
{ "name": "vinyard view", "cuisine": null }
];
const create_cuisine = name => ({ name, "venues": [] });
const unique = () => {
const seen = {};
return item => {
const json = JSON.stringify( item );
return seen.hasOwnProperty( json )
? false
: ( seen[ json ] = true );
};
};
// Filter away all the restaurants without a cuisine value.
const restaurants_with_cuisine = restaurants.filter( restaurant => restaurant.cuisine );
const cuisines = restaurants_with_cuisine
// Extract the cuisine anmes from the restaurants.
.map( restaurant => restaurant.cuisine )
// Filter aways all the duplicates.
.filter( unique() )
// Create a new cuisine object.
.map( cuisine_name => create_cuisine( cuisine_name ));
// Finally add all the restaurant names to the right cuisine.
restaurants_with_cuisine.forEach( restaurant => cuisines.find( cuisine => cuisine.name === restaurant.cuisine ).venues.push( restaurant.name ));
console.log( cuisines );
Using a few es6 features, we can generate this list with Set, map and filter.
We will first map a list of cuisines, and remove invalid ones such as undefined. With that we will use a Set to create a unique list of cuisines.
Next we will take that list and map it again to return the final object, by filtering the original object where the cuisine matches the current iteration. Finally we map the filtered results to return just the name to the venueNames object.
Our result will look like this:
function getItems(places) {
// Get a unique list of cuisines
return [...new Set(places.map(p => p.cuisine).filter(c => c))]
// Build the result
.map(c => {
return {
[c]: {
// Get a list of cuisines that match the current cuisine
venueNames: places.filter(p => p.cuisine == c).map(c => c.name)
}
}
})
}
const places = [
{"name": "angelinas"},
{"name": "besuto"},
{"name": "catch","cuisine": "Japanese"},
{"name": "center cut"},
{"name": "fedora"},
{"name": "Habanero","cuisine": "Mexican"},
{"name": "Indies"},
{"name": "new"},
{"name": "RazINN"},
{"name": "restaurantTestVenue779"},
{"name": "restaurantTestVenue9703"},
{"name": "Salsa ","cuisine": "Mexican"},
{"name": "Sushi Place","cuisine": "Japanese"},
{"name": "The Ashoka"},
{"name": "The Poboys"},
{"name": "the shogun"},
{"name": "vinyard view"}
]
console.log(getItems(places))
I want to hide _id to display on UI using ng-model , I see alot of examples of filtering data using ng-repeat but i did not find angular solution to achieve this task using ng-model.How can hide _id property to display ?
main.html
<div ng-jsoneditor="onLoad" ng-model="obj.data" options="obj.options" ></div>
Ctrl.js
$scope.obj.data = {
"_id": "58a3322bac70c63254ba2a9c",
"name": "MailClass",
"id": "MailTask_1",
"createdBy": "tyuru",
"__v": 0,
"properties": [{
"label": "Java Package Name",
"type": "String",
"editable": true,
"binding": {
"type": "property",
"name": "camunda:class"
},
"$$hashKey": "object:29"
}],
"appliesTo": [
"bpmn:ServiceTask"
]
}
var json = {};
function loadCurrentUserAndTemplate() {
AuthService.getCurrentUser()
.then(function(resp) {
$scope.currentUser = resp.data.id;
// console.log($scope.currentUser);
userTemplate($scope.currentUser);
});
}
loadCurrentUserAndTemplate();
$scope.obj = {
data: json,
options: {
mode: 'tree'
}
};
var privateFields = removePrivateFields($scope.obj.data, ['_id', '__v']);
// add private fields back to $scope.obj.data before POST
var modifiedData = Object.assign({}, $scope.obj.data, privateFields);
function removePrivateFields(obj, props) {
var output = {};
props.forEach(function(prop) {
if (obj.hasOwnProperty(prop)) {
output[prop] = obj[prop];
delete obj[prop];
}
});
return output;
}
function userTemplate(user) {
// console.log('inside template',$scope.currentUser);
templateService.getUserTemplates(user)
.then(function(response) {
// console.log('userTemplate',response.data);
// console.log(response.data.length);
$scope.displayedTemplates = response.data;
if (response.data.length !== 0 && response.data !== null) {
$scope.obj.data = response.data[0];
}
}
you can create a function like removePrivateFields to strip the private fields from original object and attach them back to the modified object before submitting to server
// for testing
var $scope = { obj: {} };
var jsonData = {
"_id": "58a3322bac70c63254ba2a9c",
"name": "MailClass",
"id": "MailTask_1",
"createdBy": "tyuru",
"__v": 0,
"properties": [{
"label": "Java Package Name",
"type": "String",
"editable": true,
"binding": {
"type": "property",
"name": "camunda:class"
},
"$$hashKey": "object:29"
}],
"appliesTo": [
"bpmn:ServiceTask"
]
};
var privateFields = removePrivateFields(jsonData, ['_id', '__v']);
// private fields got removed form actual jsonData
$scope.obj.data = jsonData;
console.log($scope.obj.data);
// once edit
// add private fields back to $scope.obj.data before POST
var modifiedData = Object.assign({}, $scope.obj.data, privateFields);
console.log(modifiedData);
function removePrivateFields(obj, props) {
var output = {};
props.forEach(function(prop) {
if (obj.hasOwnProperty(prop)) {
output[prop] = obj[prop];
delete obj[prop];
}
});
return output;
}
It would be both more performant and along Angular best practices to instead delegate this functionality into your controller or the service fetching the object.
Ideally, you want to perform any object manipulation or formatting within an Angular service, but you could also do it within your controller (probably fine if you're just instantiating your JSON editor with mock data).
Given
The url root is: https://myApp.firebaseio.com
And
The data is:
{
"users": {
"u00001": {
"name": "Andy",
"teams": {
"t001": true,
"t003": true
}
},
...
},
"teams": {
"t001": {
"name": "Alpha Team"
},
"t002": {
"name": "Beta Team"
},
"t003": {
"name": "Gamma Team"
},
...
}
}
And
The teams Andy joins are ['t001', 't003']
Question:
Is it possible to use ONE query to get all the names of the teams that Andy joins? (find all the team names, where IDs are in ['t001', 't003'], e.g. expect ["Alpha Team", "Gamma Team"] )
Thanks in advance.
This should work:
var ref = new Firebase('https://myApp.firebaseio.com');
ref.child('users/u00001/teams').on('value', function(teamKeys) {
var teamNames = [];
teamKeys.forEach(function(teamKey) {
ref.child('teams').child(teamKey.key()).once('value', function(teamSnapshot) {
teamNames.push(teamSnapshot.val().name);
if (teamNames.length == teamKeys.numChildren()) {
console.log('All team names loaded');
}
});
});
})
If you're worried about the loading time and number of round-trips, see Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly
var data = { "users": { "u00001": { "name": "Andy", "teams": { "t001": true, "t003": true } }, }, "teams": { "t001": { "name": "Alpha Team" }, "t002": { "name": "Beta Team" }, "t003": { "name": "Gamma Team" } } }
function getNames(data, user) {
var res = [];
var teams = [];
Object.keys(data.users).forEach(k => {
if (data.users[k].name == user) {
Object.keys(data.users[k].teams).forEach(t => teams.push(t))
}
});
Object.keys(data.teams).forEach(t => {
if (teams.indexOf(t) > -1) {
res.push(data.teams[t].name);
}
});
return res;
}
document.write(JSON.stringify(getNames(data, "Andy")));