angularjsodatabreezesap-gateway

Include SAP Gateway labels in Breeze custom metadata


I am building an Angular 1.3.5 app using Breeze 1.5.1 to interface with a SAP gateway server. One requirement is to minimize duplicate UI translations by re-using the human-readable metadata labels provided by the server. From what I can gather, Breeze's support for custom metadata properties should allow me to load these labels alongside all the standard entity metadata, but I'm struggling to work out exactly how to approach this.

The metadata service provides data in the following format:

<EntityType Name="ContactPersonEmail" sap:content-version="1">
  <Key>
    <PropertyRef Name="email"/>
  </Key>
  <Property Name="cpGuid" Type="Edm.Guid" sap:label="Long Text String for XML and HTML Output"/>
  <Property Name="primaryEmail" Type="Edm.Boolean" Nullable="false" sap:label="Standard No."/>
  <Property Name="email" Type="Edm.String" Nullable="false" MaxLength="241" sap:label="E-Mail Address"/>
  <Property Name="homeIndicator" Type="Edm.Boolean" Nullable="false" sap:label="Home address"/>
  <Property Name="location" Type="Edm.String" Nullable="false" MaxLength="2" sap:label="Email Type"/>
  <Property Name="emailType" Type="Edm.String" Nullable="false" MaxLength="2" sap:label="Email Type"/>
  <Property Name="emailTypeText" Type="Edm.String" Nullable="false" MaxLength="60"/>
</EntityType>

where the sap:label attribute is the text I want to add to the Breeze entity type. Is this feasible? The Breeze documentation mostly seems to be focused on loading custom metadata from a local file or already-loaded data, rather than including an additional property on data load, so perhaps this approach is naive.

Once this is resolved I'll work out how to get the text onto the page, but that's for later.

Update: Solution

Per Jeremy's answer below, I was able to run the metadata response through an initialisation function and capture the label field via the metadataProperty's extension property. Example (pre-refactor) code as follows:

// ...
if (entityProperty) {
  if (typeof metadataProperty.extensions !== "undefined" && metadataProperty.extensions.length) {
    var extension = metadataProperty.extensions[0];
    entityProperty[extension.name] = extension.value;
  }
}
// ...

The extension.name in this instance is "label", and it's the only extension in the array where it appears. Now all that remains is to get the data onto the UI, but I'm sure that'll be trivial :)


Solution

  • I think this is possible although I'll admit I have only supplemented the Breeze Metadata JSON schema, never XML.

    When fetching the metadata on the client you'll just need to do a bit of additional processing to supplement the breeze entity type with your custom metadata properties. In the example code below four custom metadata props are added: displayName, displayOrder, autoGenerateField and allowEmptyStrings.

    function initializeMetadataStore(metadataStore, metadata) {
        var metadataType, metadataProperty, entityProperty, i, j;
        for (i = 0; i < metadata.schema.entityType.length; i++) {
            metadataType = metadata.schema.entityType[i];
            var entityType = metadataStore.getEntityType(metadataType.name);
            for (j = 0; j < metadataType.property.length; j++) {
                metadataProperty = metadataType.property[j];
                entityProperty = entityType.getProperty(metadataProperty.name);
                if (entityProperty) {
                    if (typeof metadataProperty.displayName !== 'undefined') {
                        entityProperty.displayName = metadataProperty.displayName;
                    }
                    if (typeof metadataProperty.displayOrder !== 'undefined') {
                        entityProperty.displayOrder = metadataProperty.displayOrder;
                    }
                    if (typeof metadataProperty.autoGenerateField !== 'undefined') {
                        entityProperty.autoGenerateField = metadataProperty.autoGenerateField;
                    }
                    if (typeof metadataProperty.allowEmptyStrings !== 'undefined') {
                        entityProperty.allowEmptyStrings = metadataProperty.allowEmptyStrings;
                    }
                }
            }
        }
    }
    
    var entityManager = ....something...;
    entityManager.fetchMetadata(function (metadata) {
        return initializeMetadataStore(entityManager.metadataStore, metadata);
    });
    

    Here's my answer to a similar question however the OP's backend is .NET and they're using the Breeze Metadata JSON schema.