cobolstinks
cobolstinks

Reputation: 7153

Pass collection into custom angular schematic?

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?

Upvotes: 0

Views: 1281

Answers (4)

tvsbrent
tvsbrent

Reputation: 2619

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.

Upvotes: 0

Oliver Kocsis
Oliver Kocsis

Reputation: 613

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[]
}

Upvotes: 0

cobolstinks
cobolstinks

Reputation: 7153

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!

Upvotes: 0

itay oded
itay oded

Reputation: 1040

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')

Upvotes: 0

Related Questions