Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular schematics conditional property/prompt

I'm working on creating my own schematics. This schematics will be responsible for creating a component (container) with some code. Template of this component will contain a few other components. One of this component will be banner component that will be optional. This banner will display text that will be translated into other languages, so I also should ask the user to provide (default) translation text if the banner will be included in the component. Here is an example of this template:

name@dasherize.component.html.template:

<% if (includeBanner) { %>
<app-banner [title]="'<%= translationModuleKey %>.banner.title' | translate"
                           [description]="'<%= translationModuleKey %>.banner.description' | translate">
</app-banner>
<% } %>
<app-other-component>

</app-other-component>

Here is my schema.json:

{
  "$schema": "http://json-schema.org/schema",
  "id": "MySchematics",
  "title": "My schematics",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "The name of the container",
      "x-prompt": "Container name"
    },
    "includeBanner": {
      "type": "boolean",
      "description": "Include banner",
      "default": "true",
      "x-prompt": "Include banner"
    },
    "bannerTitle": {
      "type": "string",
      "description": "Banner title",
      "x-prompt": "Banner title"
    },
    "bannerDescription": {
      "type": "string",
      "description": "Banner description",
      "x-prompt": "Banner description"
    },
    "translationModuleKey": {
      "type": "string",
      "description": "Root key for translations"
    }
  },
  "required": [
    "name", "includeBanner", "bannerTitle", "bannerDescription"
  ]
}

My problem is that when user will set includeBanner to true, fields bannerTitle and bannerDescription should be required and there should be displayed prompt if those properties were not provided, but if includeBanner will be false, bannerTitle and bannerDescription shouldn't be required and there shouldn't be displayed prompt to fill these properties if those properties were not provided. Any idea how to achieve that?

like image 535
rafcik Avatar asked Nov 07 '22 16:11

rafcik


1 Answers

I was struggling with the same problem. What I've discovered - if you need conditional prompts, then you can't rely on declarative schema.json file (it doesn't support conditions). Instead, you should use the askConfirmation function from @angular/cli/utilities/prompt. So your example could look like this:

import { askConfirmation } from '@angular/cli/utilities/prompt';

export function yourSchematicsFn(options: Schema): Rule {
    return async (tree: Tree, context: SchematicContext) => {
         const includeBanner = await askConfirmation('Include Banner?', true);
         if(includeBanner) {
              // ask for bannerTitle and bannerDescription
         }
         else {
              // do something else
         }
         return chain(/* chain your rules here */);
    }
}

I've discovered this in Angular CLI ng-add schematics source code: askConfirmation.

like image 125
Kirill Metrik Avatar answered Nov 10 '22 01:11

Kirill Metrik