2

I am creating custom schematics, which I want to use to generate component files in a separate Angular project. For this purpose I am using conditional templates relying on optional parameters declared in my schema.json file. The problem is that when I try to generate the component like this:

ng g subscription-component:component --foo --path="/app" new

I get the following error:

Error: Schematic input does not validate against the Schema: {"foo":true,"path":"/app","name":"new"}
Errors:

Data path "" must NOT have additional properties(foo).

Here is my schema.json file:

{
"$schema": "http://json-schema.org/schema",
"$id": "Schema",
"type": "object",
"properties": {
    "path": {
        "type": "string",
        "format": "path"
    },
    "name": {
        "type": "string",
        "$default": {
            "$source": "argv",
            "index": 0
        }
    },
    "foo": {
        "type": "boolean",
        "default": false
    }
},
"required": [
    "name"
]


 } 

The collection.json file in my Angular project:

{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    "component": {
      "aliases": [
        "c"
      ],
      "description": "A blank schematic.",
      "factory": "./subscription-component/index#subscriptionComponent",
      "schema": "./subscription-component/schema.json"
    }
  }
}

and my file:

import { Component, OnInit } from '@angular/core';

@Component({
    selector: 'app-<%= dasherize(name) %>-component',
    templateUrl: './<%= dasherize(name) %>.component.html',
    styleUrls: ['./<%= dasherize(name) %>.component.scss'],
})
export class <%= classify(name) %>Component implements OnInit <% if (foo) {%>, OnDestroy <% }%> {

<% if (foo) {%>
private readonly subscription: Subscription = new Subscription();
<% }%>

constructor() { }

ngOnInit(): void {
}

<% if (foo) {%>
ngOnDestroy(): void {
    this.subscription.unsubscribe();
}
<% }%>
}

Any idea how to fix this?

koilami
  • 21
  • 1
  • 3
  • 1
    Hello, what version of Angular schematics are you using ? – Alain Boudard Apr 08 '22 at 13:52
  • Hi, I am using version 13.3.2 of @angular-devkit/schematics – koilami Apr 08 '22 at 21:51
  • Ok, I tested with this version, on an empty project with the exact same schema and command line and it worked ... you can check this out : https://github.com/aboudard/angular-schematics-test the code is very simple, just to test the command. – Alain Boudard Apr 11 '22 at 13:26
  • Thank you for taking the time to answer my question. I managed to figure out what was causing the issue. In the factory function in the index.ts file, I am calling an externalSchematic from @schematics/angular to first generate a component and then I am overwriting is content. – koilami Apr 11 '22 at 15:16
  • 2
    https://gist.github.com/koilami/c3574dc873fd2ed1ea7e863cc9d97f36. Thus, the optional parameters of the custom schema.json file were passed to the external schematic. So to fix that I changed my code to this: externalSchematic('@schematics/angular', 'component', {path: _options.path, name: _options.name}). – koilami Apr 11 '22 at 15:23
  • 1
    Oh that's indeed tricky, I see exactly ! That's why we always need to get back to simpler cases to solve these problems out ! I'm glad you reloved that, Schematics are great but not easy to work with ;) – Alain Boudard Apr 11 '22 at 15:25

0 Answers0