diff --git a/frontend/src/app/card-row/card-row.component.html b/frontend/src/app/card-row/card-row.component.html
index 42301209673db46dd7a6c413ccd04b6bd375f749..0f0d89877b44004f2ff90cc4669ad2fa29a87d9b 100644
--- a/frontend/src/app/card-row/card-row.component.html
+++ b/frontend/src/app/card-row/card-row.component.html
@@ -1,4 +1,4 @@
-<ng-container *ngIf="(test && value === undefined)  || (value)">
+<ng-container *ngIf="shouldShow()">
   <div class="row row-sep">
     <div class="col-4 field my-2">
       {{ label }}
diff --git a/frontend/src/app/card-row/card-row.component.spec.ts b/frontend/src/app/card-row/card-row.component.spec.ts
index 95ab00d83c82f44f1dd4c222345ef3e7dfe75f0d..2c78f8ff82e7f1a8e0a48c573121e47086688eef 100644
--- a/frontend/src/app/card-row/card-row.component.spec.ts
+++ b/frontend/src/app/card-row/card-row.component.spec.ts
@@ -1,25 +1,128 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, TestBed } from '@angular/core/testing';
 
 import { CardRowComponent } from './card-row.component';
+import { ComponentTester, speculoosMatchers } from 'ngx-speculoos';
+import { Component, ViewChild } from '@angular/core';
+
+class CardRowComponentTester extends ComponentTester<CardRowComponent> {
+    constructor() {
+        super(CardRowComponent);
+    }
+
+    get rowDiv() {
+        return this.element('div.row');
+    }
+
+    get labelDiv() {
+        return this.element('div.field');
+    }
+
+    get valueDiv() {
+        return this.element('div.col');
+    }
+}
+
+
+/**
+ * Test gpds-card-row with a provided `ng-template`
+ */
+@Component({
+    selector: 'gpds-test',
+    template: `
+        <gpds-card-row>
+            <ng-template>
+                <strong>Value HTML template</strong>
+            </ng-template>
+        </gpds-card-row>`
+})
+class CardRowWithTemplateComponent {
+    @ViewChild(CardRowComponent) component: CardRowComponent;
+}
 
 describe('CardRowComponent', () => {
-    let component: CardRowComponent;
-    let fixture: ComponentFixture<CardRowComponent>;
+    beforeEach(() => jasmine.addMatchers(speculoosMatchers));
 
-    beforeEach(async(() => {
+    beforeEach(async(() =>
         TestBed.configureTestingModule({
-            declarations: [CardRowComponent]
-        })
-            .compileComponents();
-    }));
+            declarations: [CardRowComponent, CardRowWithTemplateComponent]
+        }).compileComponents()
+    ));
 
-    beforeEach(() => {
-        fixture = TestBed.createComponent(CardRowComponent);
-        component = fixture.componentInstance;
-        fixture.detectChanges();
+
+    it('should hide falsy value', () => {
+        const tester = new CardRowComponentTester();
+        tester.componentInstance.label = 'Label1';
+        tester.componentInstance.value = null;
+        tester.detectChanges();
+
+        expect(tester.rowDiv).toBeFalsy();
+    });
+
+    it('should show truthy value', () => {
+        const tester = new CardRowComponentTester();
+        tester.componentInstance.label = 'Label1';
+        tester.componentInstance.value = 'Value1';
+        tester.detectChanges();
+
+        expect(tester.rowDiv).toBeTruthy();
+        expect(tester.labelDiv).toContainText(tester.componentInstance.label);
+        expect(tester.valueDiv).toContainText(tester.componentInstance.value);
+    });
+
+    it('should hide falsy test', () => {
+        const tester = new CardRowComponentTester();
+        tester.componentInstance.label = 'Label1';
+        tester.componentInstance.value = 'Value1';
+        tester.componentInstance.test = false;
+        tester.detectChanges();
+
+        expect(tester.rowDiv).toBeFalsy();
+    });
+
+    it('should hide truthy test, falsy value', () => {
+        const tester = new CardRowComponentTester();
+        tester.componentInstance.label = 'Label1';
+        tester.componentInstance.value = '';
+        tester.componentInstance.test = true;
+        tester.detectChanges();
+
+        expect(tester.rowDiv).toBeFalsy();
     });
 
-    it('should create', () => {
-        expect(component).toBeTruthy();
+    it('should show truthy test, truthy value', () => {
+        const tester = new CardRowComponentTester();
+        tester.componentInstance.label = 'Label1';
+        tester.componentInstance.value = 'Value1';
+        tester.componentInstance.test = true;
+        tester.detectChanges();
+
+        expect(tester.rowDiv).toBeTruthy();
+        expect(tester.labelDiv).toContainText(tester.componentInstance.label);
+        expect(tester.valueDiv).toContainText(tester.componentInstance.value);
     });
+
+
+    it('should hide falsy test, provided template', async(() => {
+        const fixture = TestBed.createComponent(CardRowWithTemplateComponent);
+        fixture.componentInstance.component.label = 'Label1';
+        fixture.componentInstance.component.test = '';
+        fixture.detectChanges();
+
+        const element: HTMLElement = fixture.nativeElement;
+        expect(element.querySelector('div.row')).toBeFalsy();
+    }));
+
+
+    it('should show truthy test, provided template', async(() => {
+        const fixture = TestBed.createComponent(CardRowWithTemplateComponent);
+        const component = fixture.componentInstance.component;
+        component.label = 'Label2';
+        component.test = true;
+        fixture.detectChanges();
+
+        const element: HTMLElement = fixture.nativeElement;
+        expect(element.querySelector('div.row')).toBeTruthy();
+        expect(element.querySelector('div.field').textContent).toContain(component.label);
+        expect(element.querySelector('div.col').textContent).toContain('Value HTML template');
+    }));
 });
diff --git a/frontend/src/app/card-row/card-row.component.ts b/frontend/src/app/card-row/card-row.component.ts
index 9def776858b0589e60ae47c14ce1047fcc2a1c76..51e69d8b05b7ce7736f0805cd28c735d9d02906e 100644
--- a/frontend/src/app/card-row/card-row.component.ts
+++ b/frontend/src/app/card-row/card-row.component.ts
@@ -13,4 +13,13 @@ export class CardRowComponent {
 
     @ContentChild(TemplateRef) template: TemplateRef<any>;
 
+    shouldShow(): boolean {
+        return this.test && (
+            // Value not provided and template provided
+            (this.value === undefined && this.template !== undefined)
+            ||
+            // Or value truthy
+            !!this.value
+        );
+    }
 }
diff --git a/frontend/src/app/card-section/card-section.component.spec.ts b/frontend/src/app/card-section/card-section.component.spec.ts
index 874070e7d85edb2aa22393ae5ab055ea5cb0b5aa..c756a49452350b7ffddcb86486178dd9881b7eb0 100644
--- a/frontend/src/app/card-section/card-section.component.spec.ts
+++ b/frontend/src/app/card-section/card-section.component.spec.ts
@@ -1,25 +1,61 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, TestBed } from '@angular/core/testing';
 
 import { CardSectionComponent } from './card-section.component';
+import { speculoosMatchers } from 'ngx-speculoos';
+import { Component, ViewChild } from '@angular/core';
+
+
+/**
+ * Test gpds-card-section with a provided `ng-template`
+ */
+@Component({
+    selector: 'gpds-test',
+    template: `
+        <gpds-card-section>
+            <ng-template>
+                <div class="test-body">Body HTML template</div>
+            </ng-template>
+        </gpds-card-section>`
+})
+class CardSectionTestWrapperComponent {
+    @ViewChild(CardSectionComponent) component: CardSectionComponent;
+}
 
 describe('CardSectionComponent', () => {
-    let component: CardSectionComponent;
-    let fixture: ComponentFixture<CardSectionComponent>;
+    beforeEach(() => jasmine.addMatchers(speculoosMatchers));
 
-    beforeEach(async(() => {
+    beforeEach(async(() =>
         TestBed.configureTestingModule({
-            declarations: [CardSectionComponent]
-        })
-            .compileComponents();
+            declarations: [CardSectionComponent, CardSectionTestWrapperComponent]
+        }).compileComponents()
+    ));
+
+    it('should hide falsy test', async(() => {
+        const fixture = TestBed.createComponent(CardSectionTestWrapperComponent);
+        const component = fixture.componentInstance.component;
+        component.header = 'Header1';
+        component.test = '';
+        fixture.detectChanges();
+
+        const element: HTMLElement = fixture.nativeElement;
+        const cardDiv = element.querySelector('div.card');
+        expect(cardDiv).toBeFalsy();
     }));
 
-    beforeEach(() => {
-        fixture = TestBed.createComponent(CardSectionComponent);
-        component = fixture.componentInstance;
+
+    it('should show truthy test', async(() => {
+        const fixture = TestBed.createComponent(CardSectionTestWrapperComponent);
+        const component = fixture.componentInstance.component;
+        component.header = 'Header2';
+        component.test = true;
         fixture.detectChanges();
-    });
 
-    it('should create', () => {
-        expect(component).toBeTruthy();
-    });
+        const element: HTMLElement = fixture.nativeElement;
+        const cardDiv = element.querySelector('div.card');
+        const headerDiv = element.querySelector('div.card-header');
+        const bodyDiv = element.querySelector('div.test-body');
+        expect(cardDiv).toBeTruthy();
+        expect(headerDiv.textContent).toContain(component.header);
+        expect(bodyDiv.textContent).toContain('Body HTML template');
+    }));
 });
diff --git a/frontend/src/app/card-table/card-table.component.spec.ts b/frontend/src/app/card-table/card-table.component.spec.ts
index e21f25a54632d5ec9310ad09b42518d824f37dbf..da131453876bf0ceefdaafbf9bd6d1b854bdb290 100644
--- a/frontend/src/app/card-table/card-table.component.spec.ts
+++ b/frontend/src/app/card-table/card-table.component.spec.ts
@@ -1,25 +1,78 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, TestBed } from '@angular/core/testing';
 
 import { CardTableComponent } from './card-table.component';
+import { Component, ViewChild } from '@angular/core';
+
+/**
+ * Test gpds-card-table with a simple provided row `ng-template`
+ */
+@Component({
+    selector: 'gpds-test',
+    template: `
+        <gpds-card-table>
+            <ng-template let-row>
+                <tr>
+                    <td>{{ row[0] }}</td>
+                    <td>{{ row[1] }}</td>
+                    <td>{{ row[2] }}</td>
+                </tr>
+            </ng-template>
+        </gpds-card-table>`
+})
+class CardTableTestWrapperComponent {
+    @ViewChild(CardTableComponent) component: CardTableComponent;
+}
 
 describe('CardTableComponent', () => {
-    let component: CardTableComponent;
-    let fixture: ComponentFixture<CardTableComponent>;
 
-    beforeEach(async(() => {
+    beforeEach(async(() =>
         TestBed.configureTestingModule({
-            declarations: [CardTableComponent]
-        })
-            .compileComponents();
-    }));
-
-    beforeEach(() => {
-        fixture = TestBed.createComponent(CardTableComponent);
-        component = fixture.componentInstance;
+            declarations: [CardTableComponent, CardTableTestWrapperComponent]
+        }).compileComponents()
+    ));
+
+    const headers = [
+        'h1', 'h2', 'h3'
+    ];
+    const rows = [
+        ['a', 'b', 'c'],
+        ['d', 'e', 'f'],
+        ['g', 'h', 'i'],
+    ];
+
+    it('should hide headers and show rows', () => {
+        const fixture = TestBed.createComponent(CardTableTestWrapperComponent);
+        const component = fixture.componentInstance.component;
+        component.headers = null;
+        component.rows = rows;
         fixture.detectChanges();
+
+        const element: HTMLElement = fixture.nativeElement;
+        const thead = element.querySelector('thead');
+        expect(thead).toBeFalsy();
+
+        const tds = element.querySelectorAll('td');
+        expect(tds.length).toBe(9);
+        expect(tds[0].textContent).toContain(rows[0][0]);
+        expect(tds[5].textContent).toContain(rows[1][2]);
     });
 
-    it('should create', () => {
-        expect(component).toBeTruthy();
+    it('should show headers and rows', () => {
+        const fixture = TestBed.createComponent(CardTableTestWrapperComponent);
+        const component = fixture.componentInstance.component;
+        component.headers = headers;
+        component.rows = rows;
+        fixture.detectChanges();
+
+        const element: HTMLElement = fixture.nativeElement;
+        const ths = element.querySelectorAll('thead th');
+        expect(ths.length).toBe(3);
+        expect(ths[0].textContent).toContain(headers[0]);
+        expect(ths[2].textContent).toContain(headers[2]);
+
+        const tds = element.querySelectorAll('td');
+        expect(tds.length).toBe(9);
+        expect(tds[0].textContent).toContain(rows[0][0]);
+        expect(tds[5].textContent).toContain(rows[1][2]);
     });
 });
diff --git a/frontend/src/app/form/form.component.html b/frontend/src/app/form/form.component.html
index f0ffe68003cb3aa53f209e2d2dbaf9c583cfe4c2..8afaa32eb25f3fd1322ecc6651f584edebdcc2c6 100644
--- a/frontend/src/app/form/form.component.html
+++ b/frontend/src/app/form/form.component.html
@@ -1,22 +1,22 @@
 <ul class="nav nav-tabs">
   <li class="nav-item">
     <a tabindex="0"
-       class="nav-link {{ activeTab == 'Germplasm' ? 'active' : ''}}"
-       (click)="activeTab='Germplasm'">
-      Germplasm
+       class="nav-link germplasm {{ getNavClass(tabs.GERMPLASM) }}"
+       (click)="activeTab=tabs.GERMPLASM">
+      {{ tabs.GERMPLASM }}
     </a>
   </li>
   <li class="nav-item">
     <a tabindex="1"
-       class="nav-link {{ activeTab == 'Variable' ? 'active' : ''}}"
-       (click)="activeTab='Variable'">
-      Trait
+       class="nav-link trait {{ getNavClass(tabs.TRAIT) }}"
+       (click)="activeTab=tabs.TRAIT">
+      {{ tabs.TRAIT }}
     </a>
   </li>
 </ul>
 
 <!-- Germplasm tab -->
-<div class="{{ activeTab == 'Germplasm' ? 'visible' : 'd-none' }}">
+<div class="germplasm {{ getTabClass(tabs.GERMPLASM) }}">
   <!-- Input for the crops field -->
   <div class="form-group row pt-3">
     <label for="crops" class="col-sm-4">
@@ -70,8 +70,8 @@
   </div>
 </div>
 
-<!-- Variable tab -->
-<div class="{{ activeTab == 'Variable' ? 'visible' : 'd-none' }}">
+<!-- Trait tab -->
+<div class="trait {{ getTabClass(tabs.TRAIT) }}">
   <gpds-trait-ontology-widget
     [criteria$]="criteria$"
     (initialized)="traitWidgetInitialized.emit($event)">
diff --git a/frontend/src/app/form/form.component.spec.ts b/frontend/src/app/form/form.component.spec.ts
index 54ced3d310c6020efa3a41e9db34b0165ac107ca..64edc68383f9f1a955177b69a8db00d9962d41f5 100644
--- a/frontend/src/app/form/form.component.spec.ts
+++ b/frontend/src/app/form/form.component.spec.ts
@@ -1,33 +1,71 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, TestBed } from '@angular/core/testing';
 
 import { FormComponent } from './form.component';
-import { Component, NO_ERRORS_SCHEMA } from '@angular/core';
-
+import { Component, EventEmitter, Input, Output } from '@angular/core';
 
+/**
+ * Mock gpds-suggestion-field
+ */
 @Component({
     selector: 'gpds-suggestion-field',
     template: '<br/>'
 })
-class MockFieldComponent {
+class MockSuggestionFieldComponent {
+    @Input() criteria$: any;
+}
+
+/**
+ * Mock gpds-trait-ontology-widget
+ */
+@Component({
+    selector: 'gpds-trait-ontology-widget',
+    template: '<br/>'
+})
+class MockTraitWidgetComponent {
+    @Input() criteria$: any;
+    @Output() initialized = new EventEmitter();
 }
 
 describe('FormComponent', () => {
-    let component: FormComponent;
-    let fixture: ComponentFixture<FormComponent>;
 
-    beforeEach(() => {
+    beforeEach(async(() =>
         TestBed.configureTestingModule({
-            declarations: [FormComponent, MockFieldComponent],
-            schemas: [NO_ERRORS_SCHEMA]
-        }).compileComponents();
+            declarations: [FormComponent, MockSuggestionFieldComponent, MockTraitWidgetComponent],
+        }).compileComponents()
+    ));
 
-        fixture = TestBed.createComponent(FormComponent);
-        component = fixture.componentInstance;
+    it('should switch tabs', async(() => {
+        const fixture = TestBed.createComponent(FormComponent);
         fixture.detectChanges();
-    });
 
-    it('should create', () => {
+        const element: HTMLElement = fixture.nativeElement;
+        const germplasmNav: HTMLElement = element.querySelector('a.germplasm');
+        const germplasmTab: HTMLElement = element.querySelector('div.germplasm');
+        const traitNav: HTMLElement = element.querySelector('a.trait');
+        const traitTab: HTMLElement = element.querySelector('div.trait');
+
+        // Check default tab is active
+        expect(germplasmNav.getAttribute('class')).toContain('active');
+        expect(germplasmTab.getAttribute('class')).toContain('visible');
+        expect(traitNav.getAttribute('class')).not.toContain('active');
+        expect(traitTab.getAttribute('class')).toContain('d-none');
+
+        traitNav.click();
+        fixture.detectChanges();
+
+        // Check tab switched
+        expect(traitNav.getAttribute('class')).toContain('active');
+        expect(traitTab.getAttribute('class')).toContain('visible');
+        expect(germplasmNav.getAttribute('class')).not.toContain('active');
+        expect(germplasmTab.getAttribute('class')).toContain('d-none');
+
+        germplasmNav.click();
         fixture.detectChanges();
-        expect(component).toBeTruthy();
-    });
+
+        // Check tab switched back
+        expect(germplasmNav.getAttribute('class')).toContain('active');
+        expect(germplasmTab.getAttribute('class')).toContain('visible');
+        expect(traitNav.getAttribute('class')).not.toContain('active');
+        expect(traitTab.getAttribute('class')).toContain('d-none');
+    }));
 });
diff --git a/frontend/src/app/form/form.component.ts b/frontend/src/app/form/form.component.ts
index b546c41a84870bf690f8fc60c1751a898ff00838..c2d37198bea1f6cf5bf70dc923555cd94be995f2 100644
--- a/frontend/src/app/form/form.component.ts
+++ b/frontend/src/app/form/form.component.ts
@@ -2,6 +2,11 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
 import { DataDiscoveryCriteria } from '../models/data-discovery.model';
 import { BehaviorSubject } from 'rxjs';
 
+enum Tabs {
+    GERMPLASM = 'Germplasm',
+    TRAIT = 'Trait'
+}
+
 @Component({
     selector: 'gpds-form',
     templateUrl: './form.component.html',
@@ -10,5 +15,18 @@ import { BehaviorSubject } from 'rxjs';
 export class FormComponent {
     @Input() criteria$: BehaviorSubject<DataDiscoveryCriteria>;
     @Output() traitWidgetInitialized = new EventEmitter();
-    activeTab = 'Germplasm';
+
+    // Default active tab
+    activeTab: Tabs = Tabs.GERMPLASM;
+
+    // to give access in HTML template
+    tabs = Tabs;
+
+    getNavClass(tab: Tabs) {
+        return this.activeTab === tab ? 'active' : '';
+    }
+
+    getTabClass(tab: Tabs) {
+        return this.activeTab === tab ? 'visible' : 'd-none';
+    }
 }
diff --git a/frontend/src/app/site-card/site-card.component.ts b/frontend/src/app/site-card/site-card.component.ts
index 0705744e73ececc2b0b0bef39dad3febdcdfc859..67888dcf1284bad1c061ddd166bd168e73e4cdcf 100644
--- a/frontend/src/app/site-card/site-card.component.ts
+++ b/frontend/src/app/site-card/site-card.component.ts
@@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
 import { BrapiService } from '../brapi.service';
 import { ActivatedRoute } from '@angular/router';
 import { BrapiLocation } from '../models/brapi.model';
-import { KeyValueObject } from '../utils';
+import { KeyValueObject, toKeyValueObjects } from '../utils';
 import { DataDiscoverySource } from '../models/data-discovery.model';
 import { GnpisService } from '../gnpis.service';
 
@@ -30,7 +30,7 @@ export class SiteCardComponent implements OnInit {
                     this.location = response.result;
                     this.additionalInfos = [];
                     if (this.location.additionalInfo) {
-                        this.manageAdditionalInfo(KeyValueObject.fromObject(this.location.additionalInfo).sort());
+                        this.manageAdditionalInfo(toKeyValueObjects(this.location.additionalInfo).sort());
                     }
                     const sourceURI = location['schema:includedInDataCatalog'];
                     // TODO Remove the condition when the field includedInDataCatalog will be added to URGI study.
diff --git a/frontend/src/app/study-card/study-card.component.ts b/frontend/src/app/study-card/study-card.component.ts
index 27188c0189f62ab41e9f2020ab3c8603377c0f9b..8b85644152ceb9519f958973250b2bfaa322ac7f 100644
--- a/frontend/src/app/study-card/study-card.component.ts
+++ b/frontend/src/app/study-card/study-card.component.ts
@@ -5,7 +5,7 @@ import { BrapiGermplasm, BrapiObservationVariable, BrapiStudy, BrapiTrial } from
 
 import { GnpisService } from '../gnpis.service';
 import { DataDiscoverySource } from '../models/data-discovery.model';
-import { KeyValueObject } from '../utils';
+import { KeyValueObject, toKeyValueObjects } from '../utils';
 
 @Component({
     selector: 'gpds-study-card',
@@ -43,7 +43,7 @@ export class StudyCardComponent implements OnInit {
 
                     this.additionalInfos = [];
                     if (this.study.additionalInfo) {
-                        this.additionalInfos = KeyValueObject.fromObject(this.study.additionalInfo).sort();
+                        this.additionalInfos = toKeyValueObjects(this.study.additionalInfo).sort();
                     }
 
                     // Get study trials
diff --git a/frontend/src/app/utils.spec.ts b/frontend/src/app/utils.spec.ts
index 104068ba0aad25cb4d38fee6382513a84034823f..c1d7e6e13d87d6bde404cc55e762422d0b7a51d2 100644
--- a/frontend/src/app/utils.spec.ts
+++ b/frontend/src/app/utils.spec.ts
@@ -1,10 +1,10 @@
-import { KeyValueObject } from './utils';
+import { KeyValueObject, toKeyValueObjects } from './utils';
 
 
 describe('KeyValueObject', () => {
 
     it('should convert JS object to array of KeyValueObject', () => {
-        const actual = KeyValueObject.fromObject({
+        const actual = toKeyValueObjects({
             'a': '1',
             'b': '2',
             'c': null,
@@ -13,10 +13,10 @@ describe('KeyValueObject', () => {
             'f': '3'
         });
 
-        const expected = [
-            new KeyValueObject('a', '1'),
-            new KeyValueObject('b', '2'),
-            new KeyValueObject('f', '3'),
+        const expected: KeyValueObject[] = [
+            { key: 'a', value: '1' },
+            { key: 'b', value: '2' },
+            { key: 'f', value: '3' },
         ];
 
         expect(actual).toEqual(expected);
diff --git a/frontend/src/app/utils.ts b/frontend/src/app/utils.ts
index 939ddd372352b866e7bdfd07d25355d67f7c983a..85f6ea9fcfbae1c795578d018f2fe57ee09dfef2 100644
--- a/frontend/src/app/utils.ts
+++ b/frontend/src/app/utils.ts
@@ -8,19 +8,18 @@ export function asArray<T>(obj: T | T[]): T[] {
     return [obj];
 }
 
-export class KeyValueObject {
-    public key: string;
-    public value: string;
-
-    constructor(key: string, value: string) {
-        this.key = key;
-        this.value = value;
-    }
+export interface KeyValueObject {
+    key: string;
+    value: string;
+}
 
-    static fromObject(o: { [key: string]: string }): KeyValueObject[] {
-        return Object.entries(o)
+/**
+ * Transform an object with string keys and values to a list of `KeyValueObject`.
+ * Also makes sure the keys and values are truthy.
+ */
+export function toKeyValueObjects(object: Record<string, string>): KeyValueObject[] {
+    return Object.entries(object)
             .filter(([key, value]) => !!key && !!value)
-            .map(([key, value]) => new KeyValueObject(key, value));
-    }
+            .map(([key, value]) => ({ key, value }));
 }