diff --git a/CHANGELOG.md b/CHANGELOG.md index fa36527d..75a810ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ x.x.x Release notes (xxxx-xx-xx) * None. ### Enhancements +* Added `isEmpty()` method on `Realm.Results` and `Realm.List`. * Added schema change listener to `Realm.addListener()` (#1825). ### Bug fixes diff --git a/docs/collection.js b/docs/collection.js index da289d44..53e5e7ed 100644 --- a/docs/collection.js +++ b/docs/collection.js @@ -63,6 +63,13 @@ class Collection { */ isValid() {} + /** + * Checks if this collection is empty. + * @returns {boolean} indicating if the collection is empty or not. + * @since 2.7.0 + */ + isEmpty() {} + /** * Returns new _Results_ that represent this collection being filtered by the provided query. * diff --git a/lib/index.d.ts b/lib/index.d.ts index d0843bf4..d89e0958 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -150,6 +150,11 @@ declare namespace Realm { */ isValid(): boolean; + /** + * @returns boolean + */ + isEmpty(): boolean; + min(property?: string): number | Date | null; max(property?: string): number | Date | null; sum(property?: string): number | null; diff --git a/src/js_list.hpp b/src/js_list.hpp index 250ee11a..ae4af82f 100644 --- a/src/js_list.hpp +++ b/src/js_list.hpp @@ -74,6 +74,7 @@ struct ListClass : ClassDefinition, CollectionClass> { static void filtered(ContextType, ObjectType, Arguments, ReturnValue &); static void sorted(ContextType, ObjectType, Arguments, ReturnValue &); static void is_valid(ContextType, ObjectType, Arguments, ReturnValue &); + static void is_empty(ContextType, ObjectType, Arguments, ReturnValue &); static void index_of(ContextType, ObjectType, Arguments, ReturnValue &); // observable @@ -93,6 +94,7 @@ struct ListClass : ClassDefinition, CollectionClass> { {"filtered", wrap}, {"sorted", wrap}, {"isValid", wrap}, + {"isEmpty", wrap}, {"indexOf", wrap}, {"min", wrap, AggregateFunc::Min>>}, {"max", wrap, AggregateFunc::Max>>}, @@ -272,6 +274,11 @@ void ListClass::is_valid(ContextType ctx, ObjectType this_object, Arguments a return_value.set(get_internal>(this_object)->is_valid()); } +template +void ListClass::is_empty(ContextType ctx, ObjectType this_object, Arguments args, ReturnValue &return_value) { + return_value.set(get_internal>(this_object)->size() == 0); +} + template void ListClass::index_of(ContextType ctx, ObjectType this_object, Arguments args, ReturnValue &return_value) { auto fn = [&](auto&& row) { diff --git a/src/js_results.hpp b/src/js_results.hpp index 5e11c94a..f2ab1772 100644 --- a/src/js_results.hpp +++ b/src/js_results.hpp @@ -87,6 +87,7 @@ struct ResultsClass : ClassDefinition, CollectionClass< static void filtered(ContextType, ObjectType, Arguments, ReturnValue &); static void sorted(ContextType, ObjectType, Arguments, ReturnValue &); static void is_valid(ContextType, ObjectType, Arguments, ReturnValue &); + static void is_empty(ContextType, ObjectType, Arguments, ReturnValue &); #if REALM_ENABLE_SYNC static void subscribe(ContextType, ObjectType, Arguments, ReturnValue &); #endif @@ -115,6 +116,7 @@ struct ResultsClass : ClassDefinition, CollectionClass< {"filtered", wrap}, {"sorted", wrap}, {"isValid", wrap}, + {"isEmpty", wrap}, #if REALM_ENABLE_SYNC {"subscribe", wrap}, #endif @@ -283,6 +285,11 @@ void ResultsClass::is_valid(ContextType ctx, ObjectType this_object, Argument return_value.set(get_internal>(this_object)->is_valid()); } +template +void ResultsClass::is_empty(ContextType ctx, ObjectType this_object, Arguments args, ReturnValue &return_value) { + return_value.set(get_internal>(this_object)->size() == 0); +} + #if REALM_ENABLE_SYNC template void ResultsClass::subscribe(ContextType ctx, ObjectType this_object, Arguments args, ReturnValue &return_value) { diff --git a/tests/js/list-tests.js b/tests/js/list-tests.js index 72349803..aea5af9d 100644 --- a/tests/js/list-tests.js +++ b/tests/js/list-tests.js @@ -1002,6 +1002,28 @@ module.exports = { TestCase.assertThrowsContaining(() => list.length, 'invalidated'); }, + testIsEmpty: function () { + const realm = new Realm({ schema: [schemas.PersonObject, schemas.PersonList] }); + let object; + realm.write(() => { + object = realm.create('PersonList', { + list: [ + ] + }); + }); + TestCase.assertTrue(object.list.isEmpty()); + + realm.write(() => { + object.list = [ + { name: 'Bob', age: 42 }, + { name: 'Alice', age: 42 } + ] + }); + TestCase.assertFalse(object.list.isEmpty()); + + realm.close(); + }, + testListAggregateFunctions: function() { const NullableBasicTypesList = { name: 'NullableBasicTypesList', @@ -1301,5 +1323,5 @@ module.exports = { TestCase.assertEqual(objects[1].list1[0], "Foo"); TestCase.assertEqual(objects[1].list2.length, 1); TestCase.assertEqual(objects[1].list2[0], "Bar"); - } + }, }; diff --git a/tests/js/results-tests.js b/tests/js/results-tests.js index a6fd668b..adb345bf 100644 --- a/tests/js/results-tests.js +++ b/tests/js/results-tests.js @@ -334,6 +334,17 @@ module.exports = { }); }, + testIsEmpty: function () { + let realm = new Realm({ schema: [schemas.TestObject] }); + let result = realm.objects('TestObject'); + TestCase.assertTrue(result.isEmpty()); + realm.write(function () { + realm.create('TestObject', { doubleCol: 42 }); + }); + TestCase.assertFalse(result.isEmpty()); + realm.close(); + }, + testResultsDeletedObjects: function() { var realm = new Realm({schema: [schemas.TestObject]});