Using an input element to reference a json - javascript

bit of background: when a user clicks an element, it loads a form retrieved by an ajax call. I save a copy of the json in the controller, and when they change a value, it is to update the local json.
Let's say the json is something like this:
{
name: "questions!",
id: "0",
questions: [{
id: "1",
text: "ninjas or pirates?",
type: "radio",
answers: [{
id: "1",
text: "ninjas"
} , {
id: "2",
text: "pirates"
}],
}, {
id: "3",
text: "why?",
type: "text"
answers: []
}]
}
the element returned is a jquery-ized version of the input that was selected.
While I could iterate through each field and check, I can't help but feel like there is a better way to do it and reference it more directly. How would this be done?

Related

Unflattening line items in inputData when rendered by function

I have dynamic children input fields that need to be rendered in a function, but when they are, then they are not included in inputData properly/not under the parent input field's key. When the children are included directly in the inputFields, it works as expected, but I can't use a function within the children array with Zapier.
Here is the inputData currently, when the line items are rendered in a function, the LI_ denotes that it is a child input key -
"inputData": {
"supplier": "1",
"LI_budget": 1,
"LI_tax": 1,
"company": "1",
"currency": "1",
"LI_price": "1",
"LI_description": "1"
}
I'm expecting ("parent" is the inputField parent key here):
"inputData": {
"supplier": "1",
"parent": [{
"LI_budget": 1,
"LI_tax": 1,
"LI_price": "1",
"LI_description": "1"
}],
"company": "1",
"currency": "1",
}
This is the function I'm using to pull in the parent and children input fields:
const getLineItems = async (z, bundle) => {
let lineItem = {
key: 'parent',
children: [{
key: 'LI_description',
label: 'Description',
required: true
},
{
key: 'LI_budget',
required: true,
label: 'Budget',
dynamic: 'budget.id'
},
{
key: 'LI_price',
required: true,
type: 'number',
label: 'Unit price',
helpText: 'Example: 50.25'
},
{
key: 'LI_tax',
required: true,
label: 'Tax Rate',
dynamic: 'tax_rate.id'
},
]
}
return [lineItem];
};
There are dynamic fields generated in the getLineItems function that I took out to simplify. TIA
Caleb here from Zapier Platform Support. This is a tough one! We have a pretty long-standing issue report on our platform for supporting custom fields with parent keys (it boils down to a chicken vs the egg problem that really makes my head spin when I read the discussion on the issue). Your inputFields function is spot-on, it's just a matter of properly storing it in the bundle on our part.
I think we could cobble together a workaround to unflatten it. Before I do that though, could you give this a test in the editor and submit actual line items from a previous step to this step? I'm not sure what the inputData looks like (e.g. if multiple items are split like 1,2,3 or in some other fashion). If you want to iterate on this, it might be better to switch over to our public developer Slack (http://zpr.io/ttvdr); then we can post the results here for the next person to run into this. 😁

JSON.parse not returning the orginal object

I am storing a java script object in the DB by converting that into the string by using JSON.stringify, But when i want to retrieve that object from DB i use the JSON.parse. But the JSON.parse is not returning the original object. In the below console screenshot it can be seen that the object Obj had some changes after it is converted into string and then parsed. So how can i get back the original object after doing JSON.stringify
The Object is as below:
var Obj = {
onchange: function(){
},
validate: function(obj){
},
elements: {
"list": {
menu: [{
caption: "Append an",
action: Xonomy.newElementChild,
actionParameter: "dd"
}]
},
"item": {
menu: [{
caption: "Add ",
action: Xonomy.newAttribute,
actionParameter: {name: "label", value: "something"},
hideIf: function(jsElement){
return jsElement.hasAttribute("label");
}
}, {
caption: "Delete this ",
action: Xonomy.deleteElement
}, {
caption: "New before this",
action: Xonomy.newElementBefore,
actionParameter: "sas"
}, {
caption: "New after this",
action: Xonomy.newElementAfter,
actionParameter: "aa"
}],
canDropTo: ["list"],
attributes: {
"label": {
asker: Xonomy.askString,
menu: [{
caption: "Delete this",
action: Xonomy.deleteAttribute
}]
}
}
}
}
};
As already mentioned in comments - you can't serialize JS functions with JSON.stringify. Please take a look at serialize-javascript library to store the functions.

Adding/removing items dynamically from JSON data parse from mySQL Database with Javascript

I have a mysql database with column ID, NAME , TYPE.
The database is then parsed in JSON structure as follows
[
{id: "1", name: "Snatch", type: "crime"},
{id: "2", name: "Witches of Eastwick", type: "comedy"},
{id: "3", name: "X-Men", type: "action"},
{id: "4", name: "Ordinary People", type: "drama"},
{id: "5", name: "Billy Elliot", type: "drama"},
{id: "6", name: "Toy Story", type: "children"}
]
If I want to add/remove item from the client side. How should I update it ?
I know I can use setInterval or setTimeout to refresh the table, but using this method will repopulate the table with the updated JSON object from the database.
Is there better ways to do it dynamically, with only the modified item getting updated ?
You can do it in 2 ways
1) Processing at client end.
Assume you keep the data in one variable as follows
var data = {your JSON} //Keep this variable only to identify the delta changes.
And when you submit your changes to the server just send only the delta changes.
var deltachanges = {
"added" = [
{id: "7", name: "Snatch V2", type: "crime"},
{id: "8", name: "Witches of Eastwick V2", type: "comedy"}],
"updated" = [
{id: "3", name: "X-Men - V3", type: "action"},
{id: "4", name: "Ordinary People -V4", type: "drama"}],
"deleted" = [
{id: "5", name: "Billy Elliot", type: "drama"}]
}
Now in your service just process this request with the above delta data and populate your data accordingly.
2) Processing at server side
Similar to client end processing, at the server side the delta changes has to be calculated, before it's persisted to database.

Angularjs JSON treeview, json format issue

I'm trying to implement a JSON treeview with this plugin
My issue is this line :
$scope.structure = { folders: [
{ name: 'Folder 1', files: [{ name: 'File 1.jpg' }, { name: 'File 2.png' }], folders: [
{ name: 'Subfolder 1', files: [{ name: 'Subfile 1' }] },
{ name: 'Subfolder 2' },
{ name: 'Subfolder 3' }
]},
{ name: 'Folder 2' }
]};
In my case, I'm reading a file that returns me a JSON format
[
{
"item": {
"title": "Kids"
},
"children": [
{
"item": {
"title": "HELLO"
},
"children": []
}
]
}
]
I thought using JSON.parse(myFileContent) should have been enough for having the same data structure as in the $scope.structure but the data isn't displaying, i'm not getting errors.
How can I parse my file content to make it work ?
First, the structure should be an object, since the directive differentiates "folders" from "files". So, considering you already define child elements inside a children property, you could wrap your array (assuming it's called content) into an object like so:
$scope.structure = {
"children": content
};
Then, you'll need to override the default values for the property names in which the directive will try to get the values.
$scope.structureOptions = {
foldersProperty: "children",
displayProperty: "item.title"
};
And last, you add the tree-view-options attribute to the HTML element.
<div tree-view="structure" tree-view-options="structureOptions"></div>

AngularJS : Guidance to implement a factory, service, directive or something else

I'm very new to angularjs and need some advice about the angular way to implement something very simple. In my $scope I need to set some field defaults, and these defaults are needed multiple times in my controller.
I want to be able to refactor these defaults out to a common place, to thin out the controller and allow for code reuse, but not sure if this should be a factory, directive or service.
Heres an example of the defaults:
$scope.skills = [{
description: '',
years: "1",
level: "0",
years_values: [
{ id: "1", description: "1" },
{ id: "2", description: "2" },
{ id: "3", description: "3+" }],
level_values: [
{ id: "0", description: "Starter"},
{ id: "1", description: "Intermediate"},
{ id: "2", description: "Advanced"} ]
}]
Here's an example of where I'd like to call the "new function":
skillSuccess = (resp)->
Loader.hide();
$rootScope.current_user = resp;
#TODO replace this repetition
$scope.skills = [{
description: '',
.... etc
My questions are:
Should I use a factory/directive/service, (or something else) for
this refactoring?
How do I ensure that the function gets called
initially so that the default values are available for the fields
when the page loads?
Should I use a factory/directive/service, (or something else) for this
refactoring?
I'd suggest you to create a constant because looks like you have defaults data which has initially has some value and that will going to be change by the user from the front-end. So you could place that in angular constant, then that constant will be accessed by the factory/service. And Factory/service will do the needful manipulation from its function. To make available constant in your service/factory you need to inject constant name in your service.
By looking at your current requirement you shouldn't be take consideration of directive component.
Constant
app.constant('defaults', [{
description: '',
years: "1",
level: "0",
years_values: [
{ id: "1", description: "1" },
{ id: "2", description: "2" },
{ id: "3", description: "3+" }],
level_values: [
{ id: "0", description: "Starter"},
{ id: "1", description: "Intermediate"},
{ id: "2", description: "Advanced"} ]
}]);
Service
app.service('dataService', function(defaults){
var dataService = this;
dataService.defaults = defaults;
dataService.defaults = angular.copy(defaults) //will return same copy every-time
dataService.getDefaults = function(){
return dataService.defaults;
}
//other method will lie here
})
How do I ensure that the function gets called initially so that the default values are available for the fields when the page loads?
You could simply get that defaults by consuming getDefaults method of your service, then stored that retrieved defaults and use those for manipulation.
If you want the defaults copy to instantiated every-time then use angular.copy(defaults) which will give you the copy of defaults.
Controller
app.controller('myCtrl', function($scope, dataService){
$scope.defaults = dataService.getDefaults(); //this will have defaults
//...other stuff here...
});
Should I use a factory/directive/service, (or something else) for this refactoring?
A controller should be used to set the scope, but the default values should be stored as a constant and returned by a factory. A factory pattern is preferred here because it is a singleton.
angular.module('myApp')
.factory('skillsFactory', function (defaultSkills) {
var service = {};
service.getDefaults = function () {
return defaultSkills;
};
return service;
})
.constant('defaultSkills', [{
description: '',
years: "1",
level: "0",
years_values: [{
id: "1",
description: "1"
}, {
id: "2",
description: "2"
}, {
id: "3",
description: "3+"
}],
level_values: [{
id: "0",
description: "Starter"
}, {
id: "1",
description: "Intermediate"
}, {
id: "2",
description: "Advanced"
}]
}]);
How do I ensure that the function gets called initially so that the default values are available for the fields when the page loads?
In your controller, call $scope.skills = skillsFactory.getDefaults();
angular.module('myApp')
.controller('skillsCtrl', function ($scope, skillsFactory) {
$scope.skills = skillsFactory.getDefaults();
});

Categories

Resources