Skip to content

Commit 973646e

Browse files
committed
This PR is implementing the another "result" function for the $ (selector) function .
The new "result" function `toArray()` returns an `array of strings` which is an usual array with has all selected `id's` and you can apply all appropriate arrays methods to it. The reason of this PR - in some cases, you need to get the array of strings from the `selector`, instead of use the current `each` iterator. Moreover, the source data already presented as an array of strings, so you don't need to iterate it once more time. Changed files: - `lib/javascript.d.ts`: updated declaration of `$` - the `toArray() is added; - `lib/sandbox.js`: implementation of the `toArray()` function; - `test/testFunctions.js`: test added for the `toArray()` function; - `docs/en/javascript.md`: documentation updates of the `$` function description.
1 parent af09773 commit 973646e

File tree

4 files changed

+59
-1
lines changed

4 files changed

+59
-1
lines changed

docs/en/javascript.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,7 @@ Sends to an adapter the message `unsubscribe` to inform adapter to not poll the
13521352
### $ - Selector
13531353
```js
13541354
$(selector).on(function(obj) {});
1355+
$(selector).toArray();
13551356
$(selector).each(function(id, i) {});
13561357
$(selector).setState(value, ack);
13571358
$(selector).getState();
@@ -1396,7 +1397,7 @@ Find all channels with `common.role="switch"` and belongs to `enum.rooms.Wohnzim
13961397
Take all their states, where id ends with `".STATE"` and make subscription on all these states.
13971398
If some of these states change, the callback will be called like for "on" function.
13981399

1399-
Following functions are possible, setState, getState (only from first), on, each
1400+
Following functions are possible, setState, getState (only from first), on, each, toArray
14001401

14011402
```js
14021403
// Switch on all switches in "Wohnzimmer"
@@ -1413,6 +1414,11 @@ $('channel[role=switch][state.id=*.STATE](rooms=Wohnzimmer)').each((id, i) => {
14131414
}
14141415
});
14151416
```
1417+
Or you can get a an usual array of ids and process it your own way:
1418+
```js
1419+
// get some state and filter only which has an `true` value
1420+
const enabled = $('channel[role=switch][state.id=*.STATE](rooms=Wohnzimmer)').toArray().filter((id) => getState(id)?.val === true);
1421+
```
14161422
14171423
### readFile
14181424
```js

lib/javascript.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,11 @@ declare global {
10431043
/** Contains the error if one happened */
10441044
error?: string;
10451045

1046+
/**
1047+
* Return the result as an array of state ids
1048+
*/
1049+
toArray(): Array<string>;
1050+
10461051
/**
10471052
* Executes a function for each state id in the result array
10481053
* The execution is canceled if a callback returns false

lib/sandbox.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,9 @@ function sandBox(script, name, verbose, debug, context) {
643643
// If some error in the selector
644644
if (selectorHasInvalidType || isInsideEnumString || isInsideCommonString || isInsideNativeString) {
645645
result.length = 0;
646+
result.toArray = function () {
647+
return [];
648+
};
646649
result.each = function () {
647650
return this;
648651
};
@@ -932,6 +935,9 @@ function sandBox(script, name, verbose, debug, context) {
932935
yield result[i];
933936
}
934937
};
938+
result.toArray = function () {
939+
return [...resUnique];
940+
};
935941
result.each = function (callback) {
936942
if (typeof callback === 'function') {
937943
let r;

test/testFunctions.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const expect = require('chai').expect;
2+
const { log } = require('node:console');
23
const setup = require('./lib/setup');
34

45
let objects = null;
@@ -927,6 +928,46 @@ describe.only('Test JS', function () {
927928
objects.setObject(script._id, script);
928929
});
929930

931+
it('Test JS: test $().toArray()', function (done) {
932+
this.timeout(1000);
933+
// add script
934+
const script = {
935+
_id: 'script.js.selectorToArray',
936+
type: 'script',
937+
common: {
938+
name: 'selectorToArray',
939+
enabled: true,
940+
verbose: true,
941+
engine: 'system.adapter.javascript.0',
942+
engineType: 'Javascript/js',
943+
source: `createState('selector.test_1.state', true, () => {\n` +
944+
` createState('selector.test_2.state', false, () => {\n` +
945+
` createState('selector.test_3.state', true, () => {\n` +
946+
` $(createState('selector.test_4.id', true, () => {\n` +
947+
` const states = $('state[id=javascript.0.selector.test_*.state]')` +
948+
` .toArray().filter((id) => getState(id)?.val === true);\n` +
949+
` if (Array.isArray(states)) {\n` +
950+
` createState('selector.result', states.length, true);\n` +
951+
` }\n` +
952+
` }));\n` +
953+
` });\n` +
954+
` });\n` +
955+
`});`,
956+
},
957+
native: {}
958+
};
959+
960+
const onStateChanged = function (id, state){
961+
if (id !== 'javascript.0.selector.result') return;
962+
removeStateChangedHandler(onStateChanged);
963+
expect(state.val).to.be.equal(2);
964+
done();
965+
};
966+
addStateChangedHandler(onStateChanged);
967+
objects.setObject(script._id, script);
968+
});
969+
970+
930971
it('Test JS: test stopScript', function (done) {
931972
this.timeout(5000);
932973
// add script

0 commit comments

Comments
 (0)