Skip to content

[bug] After dialog update Boolean false being sent as empty string #79

Description

@ChazUK

Describe the bug
I've had an issue when trying to process boolean values when updating components in AEM. When switching boolean values in the dialog, trying to set it to false does not send false but instead sends an empty string ''.
The dialog sets the values to be boolean, the sling model sets it to boolean, and the .model.json also shows the update as a boolean, but the angular component receives the string.

Update in Network banner_hero.model.json?_=1645206630867 {"title":"hello world","showPattern":false,":type":"eds-aem-app/components/banner-hero"}

But the console logs show pattern true {value: ''}

I would expect that the angular component is sent false instead of an empty string.

I've added some code below to try and replicate, I've got no idea how to package stuff up.

Package version
@adobe/aem-angular-editable-components@1.4.0
@adobe/aem-spa-component-mapping@1.1.1
@adobe/aem-spa-page-model-manager@1.4.0
@angular/*@13.2.0

To Reproduce

package com.business.europe.core.models;

import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.export.json.ExporterConstants;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import lombok.Getter;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;

@Model(
  adaptables = { SlingHttpServletRequest.class },
  adapters = { ComponentExporter.class },
  resourceType = BannerHeroModel.RESOURCE_TYPE,
  defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
@Exporter(
  name = ExporterConstants.SLING_MODEL_EXPORTER_NAME,
  extensions = ExporterConstants.SLING_MODEL_EXTENSION
)
@JsonInclude(Include.NON_EMPTY)
@Getter
public class BannerHeroModel implements ComponentExporter {

  protected static final String RESOURCE_TYPE =
    "eds-aem-app/components/banner-hero";

  public String getExportedType() {
    return RESOURCE_TYPE;
  }

  @ValueMapValue
  private Boolean title;

  @ValueMapValue
  private Boolean showPattern;
}

Dialog

<?xml version="1.0" encoding="UTF-8" ?>
<jcr:root
  xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
  xmlns:cq="http://www.day.com/jcr/cq/1.0"
  xmlns:jcr="http://www.jcp.org/jcr/1.0"
  xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
  xmlns:granite="http://www.adobe.com/jcr/granite/1.0"
  jcr:primaryType="nt:unstructured"
  jcr:title="Hero"
  sling:resourceType="cq/gui/components/authoring/dialog"
>
  <content
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/container"
  >
    <items jcr:primaryType="nt:unstructured">
      <tabs
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/tabs"
        maximized="{Boolean}true"
      >
        <items jcr:primaryType="nt:unstructured">
          <content
            jcr:primaryType="nt:unstructured"
            jcr:title="Content"
            sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
            margin="{Boolean}true"
          >
            <items jcr:primaryType="nt:unstructured">
              <column
                jcr:primaryType="nt:unstructured"
                sling:resourceType="granite/ui/components/coral/foundation/container"
              >
                <items jcr:primaryType="nt:unstructured">
                  <title
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                    fieldLabel="Title"
                    name="./title"
                    required="{Boolean}true"
                  />
                  <showPattern
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
                    text="Display Pattern?"
                    name="./showPattern"
                    checked="{Boolean}true"
                    value="{Boolean}true"
                    uncheckedValue="{Boolean}false"
                  />
                </items>
              </column>
            </items>
          </content>
        </items>
      </tabs>
    </items>
  </content>
</jcr:root>
import { MapTo } from '@adobe/aem-angular-editable-components';
import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';
import { Component, Input } from '@angular/core';

@Component({
  selector: 'eds-base-banner-hero',
  template: `Show Pattern: {{ showPattern }}`,
})
export class BannerHeroComponent {
  @Input() title?: string;
  @Input()
  set showPattern(value: BooleanInput) {
    this._showPattern = coerceBooleanProperty(value);
    console.log('showPattern', this._showPattern, {value});
  }
  get showPattern(): boolean {
    return this._showPattern;
  }

  private _showPattern!: boolean;
}

MapTo('eds-aem-app/components/banner-hero')(BannerHeroComponent, {
  emptyLabel: 'Hero',
  isEmpty: (cqModel: any) => !cqModel || !cqModel.title,
});

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions