Property label not found on String and there is no default value - actionscript-3

Based on the following data
public var dataArray:ArrayCollection = new ArrayCollection( [
{ label: "None", data: '' },
{ label: "Some Data", data:
{
label: "String tested at IF", data: "20"
}
}
]);
I then create a new ArrayCollection obj based on the position a user has selected from a dropdown list
var skillArrayCollection:ArrayCollection = ArrayCollection(runtimeComponents[dataArray[classSelect.selectedIndex].data]);
I am looping through an ArrayCollection object like so:
for each (var item:Object in skillArrayCollection[charSkillOne.selectedIndex]) {
if (item.label == "somelabel") {
ret = ret + Number(item.data);
}
}
When the if statement does its check 'it matches the string test and returns the correct result; IT also returns the error: ReferenceError: Error #1069: Property label not found on String and there is no default value.
I do not understand how flex will error and return the result i have asked for?

In your first object here:
{ label: "None", data: '' },
{ label: "Some Data", data:
{
label: "String tested at IF", data: "20"
}
}
data is a string, in your second object, data is an object with a label property.
When your loop goes through each element there the first would cause this error because when you call object.data.label on it you're trying to get a label property of a string, hence the error (for the second object if it were to get there it would not error). As others state the question leaves out the contents of runtimeComponents so it's difficult to say this is for sure the issue but it seems right.

Related

Parsing JSON error cannot read property 'url' of undefined

I have been trying to parse JSON, which have 3 different set of data where one element have various number of children and sometimes none. I am getting an error when there is no children present or only one present. I declared the JSON as var data.
JSON A
{
"floorplan": [
{
"title": "plan1",
"url": "https://media.plan1.pdf"
},
{
"title": "plan2",
"url": "https://media.plan2.pdf"
}
]
}
JSON B
{"floorplan": []}
JSON C
{
"floorplan": [
{
"title": "plan1",
"url": "https://media.plan1.pdf"
}
]
}
I parsed the JSON like this:
var items = JSON.parse(data);
return {
floorplan1: items.floorplan[0].url;
floorplan2: items.floorplan[1].url;
}
But, it only returned data for the JSON A, for other 2 it gave TypeError: Cannot read property 'url' of undefined.
I modified the code to check if floorplan have at least one child and then parse data.
var items = JSON.parse(data);
var plan = items.floorplan[0];
if(plan){
return {
floorplan1: items.floorplan[0].url;
floorplan2: items.floorplan[1].url;
}
}
The new code returned data for JSON A and B(as empty row), but gave error for C. C have one child still it got the error.
I also tried this code, still got the error for JSON C.
var items = JSON.parse(data);
var plan = items.floorplan[0];
var plan1;
var plan2;
if(plan){
plan1 = items.floorplan[0].url;
plan2 = items.floorplan[1].url;
}
return{
floorplan1 : plan1 ? plan1 : null;
floorplan2 : plan2 ? plan2 : null;
}
Is there any method I can try to get data returned for all 3 types of JSON?
let data = `
[{"floorplan": [{
"title": "plan1",
"url": "https://media.plan1.pdf"
}, {
"title": "plan2",
"url": "https://media.plan2.pdf"
}]},
{"floorplan": []},
{"floorplan": [{
"title": "plan1",
"url": "https://media.plan1.pdf"
}]}]`;
let json = JSON.parse(data);
//console.log(json);
json.forEach(items=>{
//console.log(items);
let o = {
floorplan1: items.floorplan.length > 0 ? items.floorplan[0].url : '',
floorplan2: items.floorplan.length > 1 ? items.floorplan[1].url : ''
};
console.log(o);
o = {
floorplan1: (items.floorplan[0] || {'url':''}).url,
floorplan2: (items.floorplan[1] || {'url':''}).url
};
console.log(o);
o = {
floorplan1: items.floorplan[0]?.url,
floorplan2: items.floorplan[1]?.url
};
console.log(o);
const {floorplan: [one = {url:''}, two = {url:''}]} = items;
o = {
floorplan1: one.url,
floorplan2: two.url
};
console.log(o);
});
Sure. A few ways, and more than I have here. I have put all the raw data into one string, parsed it into json and then iterated through that. In each loop my variable items will correspond to one of the json variables you created and referenced in your question as items.
In the first example, I check to make sure that items.floorplan has at least enough elements to contain the url I'm trying to reference, then use the ternary operator ? to output that URL if it exists or an empty string if it doesn't.
In the second example, I use the || (OR) operator to return the first object that evaluates to true. If items.floorplan[x] exists, then it will be that node, and if it doesn't I provide a default object with an empty url property on the right hand side, and then just use the url from the resulting object.
In the third, I use the optional chaining operator that was introduced in 2020. This method will return undefined if the url doesn't exist.
In the fourth example, I use destructuring to pull values out of the items variable, and make sure that there is a default value for url in case the items variable doesn't have a corresponding value.
But there are many more ways to go about it. These are just a few, and you can't necessarily say which approach is better. It's dependent on your intent and environment. With the exception of optional chaining (which shows undefined if the property doesn't exist), you can see these produce the same results.
DOCS for optional chaining: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
DOCS for destructuring: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
An article on destructuring: https://javascript.info/destructuring-assignment

TypeError: Cannot read property 'reduce' of undefined in react

I have a form in which I am asking the user to input field values for a couple of fields, storing the field values in an state and displaying the state values in a customised format.
So, I have a couple of input fields and a submit button:
<button onClick={this.handleSubmit}>Submit</button>
{
this.state.credentials &&
//<Credentials value={this.state}/>
<Credentials value={JSON.stringify(this.state, undefined, 2)} />
}
The Credentials function convert the state of the component in JSON format:
const Credentials = ({value} ) => {
return <pre>{formatState(value)}</pre>;
}
The formatState function will basically manipulate the state values and display them in the way I want:
function formatState(state) {
console.log("hi")
console.log(state);
const output = state.groups.reduce((final, s)=> {
console.log(output)
const values = Object.keys(s).reduce((out, o)=> {
out[o] = s[o].map(k => Object.values(k))
return out;
}, {})
final = {...final, ...values}
return final;
}, {})
console.log(output)
}
The state looks like this:
{
"groups": [
{
"typeA": [
{
"name": "abc"
},
{
"number": "13,14"
}
],
"typeB": [
{
"country": "xyz"
},
{
"date1": "2019-05-14"
}
]
}
]
}
But I want the output like this:
groups: {
"typeA": [[abc],[13,14]],
"typeB": [[2019-05-14],[xyz]]
}
SO, reduce function is used to convert the state into the following output. But I getting the error :
"TypeError: Cannot read property 'reduce' of undefined"
Please can anybody tell me why this is happening.
Error is here <Credentials value={JSON.stringify(this.state, undefined, 2)} />. JSON.stringify produces string representaion of some object (this.state in your case). Argument state of formatState has type of string. It seems that you want to have state arguemnt to be object. So you should do
<Credentials value={this.state} />

Variable scope & Callback woes

This program is reading through the nested object searching for a specific key & values. Once this data is found it has to initiate callback to send back the data. The object looks like this:
{
"name": "joel",
"title": "CTO",
"edu": {
"school": "RMB",
"college": "GNK",
"pg": "CDAC",
"extract": "This is a large text ..."
}
}
Here as I come from synchronous programming background I am not able to understand when I have to initiate the callback and also ensure variables are in scope
function parseData(str, callback) {
function recursiveFunction(obj) {
var keysArray = Object.keys(obj);
for (var i = 0; i < keysArray.length; i++) {
var key = keysArray[i];
var value = obj[key];
if (value === Object(value)) {
recursiveFunction(value);
}
else {
if (key == 'title') {
var title = value;
}
if (key == 'extract') {
var extract = value.replace(/(\r\n|\n|\r)/gm," ");
callback(null, JSON.stringify({title: title, text: extract}));
}
}
}
}
recursiveFunction(str, callback(null, JSON.stringify({title: title, text: extract})));
};
when this code is executed we get following error
/parseData.js:29
recursiveFunction(str, callback(null, JSON.stringify({title: title, text: extract})));
^
ReferenceError: title is not defined
Okay. So you want a function that retrieves the first property named title and the first property named extract from a nested object, no matter how deeply nested these properties are.
"Extract a property value from an object" is basically is a task in its own right, we could write a function for it.
There are three cases to handle:
The argument is not an object - return undefined
The argument contains the key in question - return the associated value
Otherwise, recurse into the object and repeat steps 1 and 2 - return according result
It could look like this:
function pluck(obj, searchKey) {
var val;
if (!obj || typeof obj !== "object") return;
if (obj.hasOwnProperty(searchKey)) return obj[searchKey];
Object.keys(obj).forEach(function (key) {
if (val) return;
val = pluck(obj[key], searchKey);
});
return val;
}
Now we can call pluck() on any object and with any key and it will return to us the first value it finds anywhere in the object.
Now the rest of your task becomes very easy:
var obj = {
"name": "joel",
"title": "CTO",
"edu": {
"school": "RMB",
"college": "GNK",
"pg": "CDAC",
"extract": "This is a large text ..."
}
}
var data = {
title: pluck(obj, "title"),
text: pluck(obj, "extract")
};
This function that you 've posted above has nothing to do with async programming. I will respond in the context of the chunk of code that you 've posted. The error that you have is because you are calling the recursiveFunction(str, callback(null, JSON.stringify({title: title, text: extract}))); but the title variable is nowhere defined. I can see a definition of the title but it is in the the context of the recursiveFunction function. The variables that you define in there are not visible outside of the scope of that function and that's why you have this error.
You are trying to do something strange in this line:
recursiveFunction(str, callback(null, JSON.stringify({title: title, text: extract})));
This line will invoke the callback and will pass in the recursiveFunction the results of this function. I would expect to see something like that in this line:
recursiveFunction(str, callback);

ExtJS 4 MVC, Get Checkbox value integer instead of bool

I'm using a form to edit Model. I receive data in JSON. Here's my problem:
I receive data for Checkbox only in INT: 1 or 0, I cannot change it. JSON:
{ "checkboxValue": 1 }
This field in ExtJS model is defined as INT type. Model:
{name: "checkboxValue", type: Ext.data.Types.INT},
then I set values to form this way:
formCmp.loadRecord(loadedStore.getAt(0));
and my checkbox is set correctly: when I receive 1 it's checked, 0 - unchecked.
But when I try to save record and send data to server this way:
form.updateRecord(form.getRecord());
record.save();
I need Checkbox to have also INT value - 1 or 0. But it has only BOOL value - true or false so when JSON is sent that value is NaN.
{
"checkboxValue": NaN
}
I think, that function .updateRecord(..) go through all elements and when it gets to checkbox it tries to get value, and the value is BOOL
Does anybody know how to make checkbox' output value INT?
Ext.form.Basic.updateForm uses getFieldValues method to retrieve new data for the updated record, while getFieldValues method returns only boolean values for checkboxes regardless of such properties as inputValue or uncheckedValue. So I would use convert function for the model's field to transform provided boolean value into an integer in a way like that:
Ext.define('MyModel', {
extend: 'Ext.data.Model',
fields: [
{
name: 'flag',
type: 'int',
convert: function (v, record) {
return typeof v === 'boolean' ? (v === true ? 1 : 0) : v;
}
}
],
...
});
Here is a complete jsfiddle
I think it can be done with some simple overrides
Ext.create('Ext.form.Panel', {
bodyPadding: 10,
width: 300,
title: 'Pizza Order',
items: [
{
xtype: 'fieldcontainer',
fieldLabel: 'Toppings',
defaultType: 'checkboxfield',
items: [
{
boxLabel : 'Topping?',
name : 'topping',
id : 'checkbox1',
// include these two properties in your checkbox config
uncheckedValue: 0,
setValue: function(checked) {
var me = this;
arguments[0] = checked ? 1 : me.uncheckedValue;
me.callParent(arguments);
return me;
}
}
]
}
],
renderTo: Ext.getBody()
});

Unable to sort Dgrid

var CustomGrid = declare([Grid, Keyboard, Selection]);
var questionGrid = new CustomGrid({
store: questionCacheStore,
columns: [
editor({
label: "Questions",
field: "question",
editor: "text",
editOn: "dblclick",
sortable:true})
],
selectionMode: "single",
cellNavigation: false
}, "questions");
I am new to Dgrid. So, please do bear with me .
i was able to populate the dgrid with a JsonStore content. But when i click on the column 'Questions', it doesn't get sorted as in local data store.instead it shows an error Uncaught TypeError: Object [object Object] has no method 'sort'. Is it required to define such a method . If so, how and where should i define it ?
I am not the person to answer your J2EE question. I asked that question recently. The solution that I found was to inject the HttpServletRequest directly. This allowed me access to the query string parameters. From there I was able to get the sort direction (ascending, descending) and column to sort. Hopefully the snippets below will help.
Example Grid Setup
require(["dojo/store/JsonRest", "dojo/store/Memory", "dojo/store/Cache",
"dojo/store/Observable", "dgrid/OnDemandGrid", "dojo/_base/declare", "dgrid/Keyboard",
"dgrid/Selection", "dojo/domReady!"],
function(JsonRest, Memory, Cache, Observable, Grid, declare, Keyboard, Selection) {
var rest = new JsonRest({target:"/POC_Admin/rest/Subcategory/", idProperty: "subcatId"});
var cache = new Cache(rest, new Memory({ idProperty: "subcatId" }));
var store = new Observable(cache);
var CustomGrid = declare([ Grid, Keyboard, Selection ]);
var grid = new CustomGrid({
columns: {
subcatId: "ID",
name: "Name"
},
store: store
}, "grid");
grid.on("dgrid-select", function(event){
// Report the item from the selected row to the console.
console.log("Row selected: ", event.rows[0].data);
});
grid.startup();
});
Example Rest GET
#Context private HttpServletRequest servletRequest;
#GET
#Path("")
#Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
public String getSubcategories(#QueryParam("name") String name) throws IOException {
//Respond to a QueryString value.
if (servletRequest.getQueryString() != null && servletRequest.getQueryString().length() > 0) {
String querystringKey = servletRequest.getQueryString();
System.out.println("QSKey = " + querystringKey);
System.out.println("Substr: " + querystringKey.substring(0, 4));
if (querystringKey.length()>4) {
if (querystringKey.substring(0, 4).contains("sort")) {
//We have the sort request.
}
}
}
//Return all results otherwise from your DAO at this point
}