I have the below dictionary which has the return type as { [key: string]: QueryBuilderFieldsDto }
{
"2221": {
"label": "Risk Domain",
"name": "2221",
"type": "dropdown",
"typeLabel": "Dropdown",
"isStandardField": false,
"fieldEntityType": 2,
"fieldEntityTypeLabel": "Risk",
"options": [{
"uniqueId": null,
"id": 2636,
"name": "Unassigned",
"isOrganizationUnit": false
}]
},
"2222": {
"label": "Number Field",
"name": "2222",
"type": "number",
"typeLabel": "Number",
"isStandardField": false,
"fieldEntityType": 2,
"fieldEntityTypeLabel": "Risk"
}
}
Properties of QueryBuilderFieldsDto
describe below
export interface QueryBuilderFieldsDto {
name: string;
label: string;
value?: string;
type: string;
nullable?: boolean;
options?: Option[] | FieldOptionsDto[];
operators?: string[];
defaultValue?: any;
defaultOperator?: any;
isStandardField: boolean;
fieldEntityType: number;
fieldEntityTypeLabel?: string;
typeLabel?: string;
validator?: (rule: Rule, parent: RuleSet) => any | null;
}
Now I want to add an extra property over the dictionary object
validator: (rule) => {
if (rule.value == undefined || rule.value == "") {
return {
age: {
rule: rule,
message: 'Value cannot be empty'
}
}
}
}
}
Example
"2222": {
"label": "Number Field",
"name": "2222",
"type": "number",
"typeLabel": "Number",
"isStandardField": false,
"fieldEntityType": 2,
"fieldEntityTypeLabel": "Risk",
validator: (rule) => {
if (rule.value == undefined || rule.value == "") {
return {
age: {
rule: rule,
message: 'Value cannot be empty'
}
}
}
}
}
}
I am subscribing to the Observable
this.metricCreateConfigureStore.queryBuilderFields$.subscribe(item => {
this.fields = item as { [key: string]: QueryBuilderFieldsDto };
})
This returns the value without validator
property, I know we use pipe
and map
to return the desired value, but not sure how to do it, the return type from the map should be
{ [key: string]: QueryBuilderFieldsDto }
The return type of queryBuilderFields
is queryBuilderFields$: Observable<{ [key: string]: QueryBuilderFieldsDto; }>
Tried something like below but got an error on vscode
CodePudding user response:
The question is basically how to map
a key/value pair in rxjs. As far as I know map
cannot do that, instead I would use reduce
. This is how I would go about it:
from(Object.entries(data)) // convert object to [key, value]
.pipe(
reduce((obj, item) => {
item[1].validator = validatorFn; // add the validator function to the value
obj[item[0]] = item[1]; // convert [key, value] back to object
return obj;
}, {})
)
.subscribe((result) => {
console.log(result);
});
EDIT: If you are expecting an asynchronous stream of data you can replace reduce with scan (docs)
CodePudding user response:
The error you see in vscode has following reason:
Map functions can be defined in full or short
map(foo => bar)
map(foo => { return bar; })
In your screenshot the curly brackets belong to the 2nd variant, which means to the map function. They do NOT belong to the object you try to return.
Either add () around {}
map(foo => ({ bar: 'baz'}))
Or add the return statement
map(foo => { return { bar: 'baz' } })
CodePudding user response:
This works for me
this.metricCreateConfigureStore.queryBuilderFields$
.map((data) => {
var mapValue: { [key: string]: Field; } = {};
Object.keys(data).forEach(key => {
mapValue[key] = this.mapField(data[key]);
});
return mapValue;
})
.subscribe(item => {
this.fields = item as { [key: string]: Field };
})
}
private mapField(field: QueryBuilderFieldsDto): Field {
const fields =
{
name: field.name,
label: field.label,
type: field.type,
typeLabel: field.typeLabel,
options: field.options,
isStandardField: field.isStandardField,
fieldEntityTypeLabel: field.fieldEntityTypeLabel,
fieldEntityType: field.fieldEntityType,
validator: (rule) => {
if (rule.value == undefined || rule.value == "") {
return {
'required': {
rule: rule,
message: 'Value cannot be empty'
}
}
}
}
} as Field;
return fields;
}