0

I want to create a custom angular schematic that can accept a collection of action names. I will then generate 3 ngrx actions for every action name provided from the user.

for example I want to create a schematic that can be invoked like this:

ng g my-collection:my-schematic --actions=GetById,GetByFirstName

Then I'll generate code for GetById, GetByIdSuccess, GetByIdError, GetByFirstName, GetByFirstNameSuccess, GetByFirstNameError.

The issue is I've only seen angular schematics that will accept a single value as an input parameter. Anyone know how to handle collections in a custom angular schematic?

cobolstinks
  • 6,801
  • 16
  • 68
  • 97

4 Answers4

0

you can follow this blog, it will teach you how to create your own schematics project:

https://blog.angular.io/schematics-an-introduction-dc1dfbc2a2b2

after you generate your schematics project in file collection.json you can extend the @ngrx/schematics:

{
...
"extends": ["@ngrx/schematics"],
}

and then use the ngrx schematics to generate 3 actions like this:

externalSchematic('@ngrx/schematics', 'action')
itay oded
  • 978
  • 13
  • 22
0

I haven't found a good example of how to an array of string into a schematic parameter, but I found a workaround. What I did was have a simple string input parameter that is consistently delimited (I used , to delimit the values). Here is my schema:

export interface Schema {
  name: string;
  path?: string;
  project?: string;
  spec?: boolean;
  actions: string;
  __actions: string[];
  store?: string;
}

I parse the actions param that is provided and generate the string array __actions and use that property in my templates. Here is a snippet from my index.ts:

export default function(options: ActionOptions): Rule {
  return (host: Tree, context: SchematicContext) => {
    options.path = getProjectPath(host, options);

    const parsedPath = parseName(options.path, options.name);
    options.name = parsedPath.name;
    options.path = parsedPath.path;
    options.__actions = options.actions.split(',');
    options.__actions = options.__actions.map(_a => classify(_a));

If you know of a better way to process these please share. Thanks!

cobolstinks
  • 6,801
  • 16
  • 68
  • 97
0

You need to pass the actions multiple times.

ng g my-collection:my-schematic --actions=GetById --actions=GetByFirstName

Define the parameter as an array within your schema.json file.

    ...
    "actions": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "The name of the actions."
    },
    ...

Also in your schema.ts.

export interface Schema {
  actions: string[]
}
Oliver Kocsis
  • 633
  • 1
  • 6
  • 12
0

If you want to pull them right off of the command args, you can do the following:

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "Sample",
  "title": "Sample Schematic",
  "type": "object",
  "description": "Does stuff.",
  "additionalProperties": false,
  "properties": {
    "things": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "$default": {
        "$source": "argv"
      },
      "description": "Things from the command-line args."
    }
  }
}

Then when you run your schematic you can do:

schematics schematic-lib:sample stuff other-stuff more-stuff

In this case, the things property will be ['stuff', 'other-stuff', 'more-stuff'].

Edit: Note that the required value in the schema won't cause the schematic to fail if you don't provide any args. You'd need to do validation on that property in your schematic.

tvsbrent
  • 2,350
  • 1
  • 10
  • 9