I have an Observable keyValue(): Observable<{[id: number]: string;}>;
The Observable's argument is:
{
[id: number]: string;
}
As you can see the second argument haven't name
Now one result of my previous Observable was:
{1: 'Bad', 2: 'Good', 3: 'Worst', 4: 'Best', 5: 'Mean'}
I need to translate as an array of:
interface NumberKeyValue {
id: number;
value: string;
}
I was trying with:
.keyValue()
.pipe(
map((kv) => {
console.log(kv);
const jsonObject = JSON.parse(JSON.stringify(kv));
console.log(jsonObject);
const nkvArray: NumberKeyValue[] = [];
for (const item of jsonObject) {
console.log(item);
const nkv: NumberKeyValue = {
id: 8, //How to catch the id number?
value: 'empty', //How to catch the string?
};
nkvArray.push(nkv);
}
return nkvArray;
})
)
.subscribe((response) => {
console.log(response);
});
After of previous code I got:
TypeError: jsonObject is not iterable
at MapSubscriber.project (template-sms.facade.ts:295)
at MapSubscriber._next (map.js:29)
at MapSubscriber.next (Subscriber.js:49)
at TapSubscriber._next (tap.js:46)
at TapSubscriber.next (Subscriber.js:49)
at SwitchMapSubscriber.notifyNext (switchMap.js:70)
at InnerSubscriber._next (InnerSubscriber.js:11)
at InnerSubscriber.next (Subscriber.js:49)
at MapSubscriber._next (map.js:35)
at MapSubscriber.next (Subscriber.js:49)
First and mainly Question:How I can to translate to one Array of my NumberKeyValue
interface?
Secondly: Is there a name for this type representation {[id: number]: string;}
?
CodePudding user response:
The object type is indeed not iterable, but you can use Object.keys
to get an array of keys that you can then use to project the data in the desired form:
.keyValue()
.pipe(
map((kv) => {
// use object destructuring to get a new reference instead of
// JSON.parse(JSON.stringify(something))
const jsonObject = { ...kv };
return Object.keys(jsonObject).map(key => ({ id: key, value: jsonObject[key] });
}),
).subscribe((response) => {
console.log(response);
});
CodePudding user response:
According to the Octavian
Answer, as you can see, a cast is needed, using key
instead of key
; and an Array of NumberKeyValue
Interface.
.keyValue()
.pipe(
map((kv) => {
const jsonObject = { ...kv };
return Object
.keys(jsonObject)
.map((key) => {
const nkv: NumberKeyValue = { id: key, value: jsonObject[ key] };
return nkv;
});
}),
)
.subscribe((response) => {
console.log(response);
});
Previously, I was thinking in archaic form.
.keyValue()
.pipe(
map((kv) => {
const numberKVArray: NumberKeyValue[] = [];
let response = JSON.stringify(kv);
response = response.replace(/[{}]/g, '');
const pairs = response.split('",');
for (const pair of pairs) {
const property = pair.split(':"');
property[0] = property[0].replace(/(^"|"$)/g, '');
property[1] = property[1].replace(/(^"|"$)/g, '');
const nkv: NumberKeyValue = {
id: property[0],
value: property[1],
};
numberKVArray.push(nkv);
}
return numberKVArray;
}),
takeUntil(this.destroy$),
)
.subscribe((response) => {
console.log(response);
});
But, The first answer is best oriented.