Angular Schematics: How to define default variables in schema.json? (projectName)

angular schematics documentation
angular.json schema
schematics/angular/utility workspace
angular schematics update file
angular material schematics
schematic worker not found in collection @schematics/angular
schematic spec not found in collection schematics/angular
schematic library not found in collection @schematics/angular

How to define default variables for angular schematics "properties" in schema.json?

I have tried to look into the angular source code itself but I couldn't figure it out. I have found out that if the keyword "$source" is being used, somehow the string in front of it will be resolved to some value.

For example "argv" and "projectName" are two variables that they will be resolved to actual values when they are written like this:

     "project": {
         "alias": "p",
         "type": "string",
         "description": "The name of the project.",
         "$default": {
             "$source": "projectName"
         }
     },

or

    "name": {
      "type": "string",
      "description": "The package name for the new schematic.",
      "$default": {
        "$source": "argv",
        "index": 0
      }
    },

So how can I define my own variable? Are they actually variables? What other variables are available?

I also found another example which is not working if I copy-paste it into my own project:

    "version": {
      "type": "string",
      "description": "The version of the Angular CLI to use.",
      "visible": false,
      "$default": {
        "$source": "ng-cli-version"
      }
    },

Here find the full code

From my observation, I expect this to be resolved to a value, but I get undefiend.

Thank you folks in advance!

The variables you define will certainly depend on the behavior for your schematic. For example, I have a new application schematic with a custom variable to allow users to specify the type of authentication to scaffold into the application:

To invoke this schematic from the command-line, the user would input ng new my-application-schematic-with-sso --collection=@simple-schematic --authentication=SSO (the x-prompt provides a list of options to the user if the command line switch is not explicitly provided. See also Angular ng-new schema for style options.

"authentication": {
    "description": "The authentication strategy to use",
    "default": "None",
    "x-prompt": {
        "message": "Which authentication strategy would you like to use?",
        "type": "list",
        "items": [
            {
                "value": "None",
                "label": "None"
            },
            {
                "value": "SSO",
                "label": "SSO"
            }
        ]
    }
},

This schematic also makes use of the argv pattern to capture the name of the workspace:

"name": {
    "description": "The name of the workspace",
    "type": "string",
    "$default": {
        "$source": "argv",
        "index": 0
    }
},...

So the command line syntax to invoke this schematic would look something like ng new my-new-schematic --collection=@simple-schematic and would generate a new workspace titled my-new-schematic. Since the --authentication flag is not provided, the user would be prompted to select either None or SSO.

One important behavior related to the schema and variables you define that can lead to the undefined issue (esp. when your variable has a default value) you noted in your original question is not correctly linking the schema to the schematic command.

For example, the schema property of the ng-new schematic object, indicates how to translate the provided CLI inputs into the corresponding object passed to your custom schematic.

{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "extends": "@schematics/angular",
  "schematics": {
    "ng-new": {
      "description": "new workspace",
      "factory": "./ng-new",
      "schema": "./ng-new/schema.json"
    }
  }
}

Two different screenshots from debugging the tests depending on whether the schema property is specified or not:

And again with the schema explicitly specified:

Angular Schematics: How to define default variables in schema.json , The variables you define will certainly depend on the behavior for your schematic​. For example, I have a new application schematic with a  You can modify these schematics, and define new ones to do things like update your code to fix breaking changes in a dependency, for example, or to add a new configuration option or framework to an existing project. Schematics that are included in the @schematics/angular collection are run by default by the commands ng generate and ng add.

Just use "default": "YOUR_VALUE" but don't forget to run npm run build after.

Angular workspace configuration, CLI defaults set at the workspace level can be overridden by defaults set at the Default project name to use in commands, where not provided as an argument. The JSON schemas for the default schematics used by the CLI to generate  You can see examples of schema files for the Angular CLI command schematics in @schematics/angular. Schematic prompts link Schematic prompts introduce user interaction into schematic execution.

Schematics for libraries, Edit the collection.json file to define the initial schema for your collection. The default path value is based on the current working directory. project : Provides a specific project to const projectName = options.project as string; const project  The dasherize is a helper function which will receive value of the name variable and convert to how @schematics/angular is the default schema.json,files/**} dist/schematics".

DevRok was almost there. I think to fully answer you question we need to look at usage of addSmartDefaultProvider. I found these references in the 7.3.x branch (because that's what we are still using at work).

Reference 1 in packages/angular/cli/models/schematic-command.ts

workflow.registry.addSmartDefaultProvider('projectName', () => {

Reference 2 in packages/angular/cli/commands/new-impl.ts

this._workflow.registry.addSmartDefaultProvider('ng-cli-version', () => version);

So it seems ng-cli-version would only work when running ng new, not ng generate. It also seems that ng-cli-version and projectName are the only defined smart default providers for now, but it should be fairly straight forward to add more in the future.

For completion sake, I'd like to reference DevRok's answer for the pseudo smart default provider of argv being defined in packages/angular/cli/utilities/json-schema.ts.

How To Use Netlify's Schematics for Angular - Part 2, will list the schematic name (if given one), a default description, and a To do this I renamed the schematic from the project name to ng-add like so: { "$schema"​: "../node_modules/@angular-devkit/schematics/collection-schema.json", The schema file is where we can define variables or enumerated  1 Angular Schematics: How to define default variables in schema.json? (projectName) Feb 15 '19. 0 terraform launching ec2 instance Feb 23. View all questions and

Not sure how you set it in the schema.json... Not sure if there is a key value pair for it ("default":"value" didn't do anything).

So I worked around with an if statement in the factory function (index.ts)

if (!_options.yourVariable) {
     _options.yourVariable = 'yourDefaultValue'
}

Works well enough.

Quick Guide to Angular Schematics: How I Built My First Schematic, Enter Angular Schematics 🤲… this is a basic quick guide to help get you started on how schematics blank --name=project-name You'll get the default set of files above when you create a blank schematics project: logic code goes; schema.json — Schematic variables ( variables that are referenced in  The file contains the factory function for the schematic to return a Rule. A rule is an operation that is performed against your filesystem. The schema.json provides a description of the schematic, available options, validation information, and default values. The initial schematic entry point contains a rule to generate a library.

"$source": "projectName" resolves to unexpected project · Issue , devkit - [ ] schematics Versions v8.11.2 6.1.0 Repro steps In a custom node_modules/@angular/cli/lib/config/schema.json", "version": 1, I expected it to resolve to "wch-site-application" because this has been set as the default project Why is this sorting done, anyway, instead of just using the value of  One cool thing about Schematics is they don’t perform any direct actions on your filesystem. Instead, you specify what you’d like to do to a Tree.The Tree is a data structure with a set of files that already exist and a staging area (of files that will contain new/updated code).

Angular - Workspace Configuration, A file named angular.json at the root level of an Angular workspace provides defaultProject: Default project name to use in commands, were not The JSON schemas for the default schematics used by the CLI to Angular defines default builders for use with the Architect tool and ng run command. schema.json — The Schematic variable Starting With A Simple Angular Schematic. With your system set up, it is time to create your first schematic. we need to determine if we need to move

Generating Custom Code With The Angular CLI And Schematics , Since some versions, the Angular CLI uses a library called Schematics to It's command line arguments are described by the file schema.json using a typing all those properties into the console, the schema.json points to defaults. For instance, "$source": "projectName" points to the Angular project in the current folder. We can just copy and adjust default Angular schematics to get useful results right now and learn more advanced APIs later when needed. (variable is set to true) schema.json. schema.d.ts

Comments
  • It's not an answer, only a coment: the best article about schematic that work (Angular 7) I've found is medium.com/rocket-fuel/…
  • That's not a good reference for this question. The closest thing I've found is this article from Hakernoon, which is still not the answer to my question.
  • Please read my question again! This is completely unrelated to my question! I'm asking about filing out the default values dynamically by the framework, not "How to give users options".
  • I'd love to take another look. I interpreted "So how can I define my own variable? Are they actually variables? What other variables are available?" as your question. Can you restate the problem you are trying to solve, i.e., "I would like to add a default value to a property in a custom schematic?" (I think I can help out and I'll amend my answer once I have that extra bit of detail from you).
  • Sure, that's great! I need the Angular CLI to populate the default value of the parameters of the running schematics command.For example, "argv" keyword is something that CLI understands and replaces it (or passes) the right value at the run-time. Or another example, as I described in the question is the {"$source": "projectName"} which would be replaced with the actual project name. What I need is to be able to tell Angular to pass a value to the command by itself to the user will not be required to write it every time.
  • For example, let's say I want to get the installed angular-core version and pass it to the schematics via a parameter.
  • That's the basic use case, the question is how to make it dynamic, not "how to provide a default value?". How to make "YOUR_VALUE" pragmatically changeable?