I have an array of devices
.
For each device I want to set the default name ("DeviceX"
- X its a sequence number) but some of them might be already used/occupied. So I need make an request to check if name already exists (ifDeviceExists()
returns true or false in response). If the name is already occupied it should increase the number and once again send request to check if that name (e.g. "Device2") already exist. If name is not occupied then it should set name of that device (device.name = "Device2").
For example - occupied devices names: "Device2"
and "Device4"
. Then the names of new created devices should be: "Device1", "Device3", "Device5", "Device6"
...
So the devices
array should be: [{name: "Device1"}, {name: "Device3"}, {name: "Device5"}, {name: "Device6"}, ... ]
The main problem for me here is that checking if name exists is async action and I do not know how to handle that (where to send request and when to subscribe) Could anyone help me with that?
CodePudding user response:
ifDeviceExists(name: string): Observable<boolean> {
return [ 'Device2', 'Device4' ].includes(name) ? of(true) : of(false);
}
findNextDeviceName(indexWrapper: { index: number }, device: Device):
Observable<{ device: Device, name:string; index: number }> {
let currentName: string;
let currentIndex = indexWrapper.index;
return interval(0).pipe(
// send requests to check name sequentially until it returns false and filter passes event
// to first() operator which will stop interval loop, NOTE: if ifDeviceExists() allways returns true,
// there will be infinite loop
concatMap(interval => {
currentIndex = currentIndex interval;
currentName = `Device${currentIndex}`;
return this.ifDeviceExists(currentName);
}),
filter(exists => !exists),
first(),
map(() => ({device, name: currentName, index: currentIndex})),
)
}
renameDevices(){
const devices = [{id: 101}, {id: 102}, {id: 103}, {id: 104}];
// this object keeps last index and allows to change it between concatMap iterations
const indexWrapper = {index: 1};
from(devices).pipe(
concatMap(device => this.findNextDeviceName(indexWrapper, device)),
map(result => {
indexWrapper.index = result.index 1;
result.device.name = result.name;
return result.device;
}),
toArray()
).subscribe({
next: (devices) => {
console.log('Devices with names', devices);
}
})
}
CodePudding user response:
const reserved = ["device2", "device5"]; //any list that contains device<X> elements
const devices = [{},{},{},{},{},{},{},{},{},{}];
let num = 0;
for (let device of devices) {
if (!reserved.includes("device" num)) {
device.name = 'device' num
};
num
}
console.log(devices)