Skip to content
This repository has been archived by the owner on Apr 3, 2024. It is now read-only.

Documentation on How to Create Handlers? #176

Open
ahwm opened this issue Oct 7, 2020 · 4 comments
Open

Documentation on How to Create Handlers? #176

ahwm opened this issue Oct 7, 2020 · 4 comments
Labels
difficulty: easy documentation Writing documentation for the Formulate.rocks website. help wanted

Comments

@ahwm
Copy link

ahwm commented Oct 7, 2020

This link: https://www.formulate.rocks/extensibility says you can create your own handlers, but I haven't found any documentation saying how you go about doing that.

I assume you implement from IFormHandlerType in some fashion (which I found while searching the source code extensively) - either directly or indirectly by inheriting from another class that implements it, but there don't seem to be any details on registering those with Formulate (the comments indicate it will just be found but that information currently requires someone to review the source code) or best practices. Also is there a way, such as in Umbraco Forms, to say the process failed for feedback to the end-user?

@Nicholas-Westby
Copy link
Contributor

Yeah, you implement IFormHandlerType. I'll see if I can write some documentation explaining the nuances (e.g., creating an AngularJS directive for the back office configuration).

IIRC, exceptions are caught and a failure indicator is returned via the API, though I'm not 100% sure about that so I'll have to review the code a bit to confirm.

I'll leave this ticket open until the documentation is created. If you feel like contributing the documentation, that would be done against this branch: https://github.com/rhythmagency/formulate/tree/gh-pages

@ahwm
Copy link
Author

ahwm commented Oct 7, 2020

I would be happy to help with writing documentation once I have a handle on how it works!

@Nicholas-Westby
Copy link
Contributor

Cool, I'll see if I can get some info to you soon to give you some background.

@Nicholas-Westby
Copy link
Contributor

@ahwm, to write the documentation, I recommend referring to the built-in form submission handlers. You'd implement a custom one in largely the same way. The store data handler may be the simplest one to refer to: https://github.com/rhythmagency/formulate/blob/v3/master/src/formulate.app/Forms/Handlers/StoreData/StoreDataHandler.cs

You can see that you must implement the interface IFormHandlerType. That's technically all that you need to do.

There are two primary methods to implement, PrepareHandleForm and HandleForm. The only difference is that the first is called synchronously as part of the form submission, and the latter is called asynchronously on a thread after the form submission has completed. You can implement neither, both, or just one.

Note that part of the interface requires you to specify an AngularJS directive that will be used to display an editing interface in the back off once the handler has been added to the form. This is useful when a handler requires some configuration to be specified. In the case of the store data handler, there is no configuration. However, there is still a directive that doesn't really do anything:

When somebody creates their own directive, they have to do things a little differently. Specifically, they can't use formulateDirectives.get, because that only returns the built-in Formulate directive markup values. Instead of using template, they'd likely want to use templateUrl and then point to an HTML file.

The send data handler is a little more interesting: https://github.com/rhythmagency/formulate/blob/v3/master/src/formulate.app/Forms/Handlers/SendData/SendDataHandler.cs

This one is using real configuration values, so the DeserializeConfiguration method does a bit of processing. You can see that it has a class that stores its configuration: https://github.com/rhythmagency/formulate/blob/v3/master/src/formulate.app/Forms/Handlers/SendData/SendDataConfiguration.cs

The other classes here are largely not important for documentation, as they are specific to the implementation of the send data handler: https://github.com/rhythmagency/formulate/tree/v3/master/src/formulate.app/Forms/Handlers/SendData

You can see the directive for the send data handler here:

You can see the HTML referencing configuration.url, configuration.method, and so on. This is how you store data in the JavaScript that is then later deserialized by the C# code.

Since you asked, here is where Formulate runs the synchronous methods on each handler: https://github.com/rhythmagency/formulate/blob/v3/master/src/formulate.api/Submissions.cs#L259-L277

You can see that it will catch any exceptions and then return a failure result. For security reasons, no additional details are returned (e.g., exception error message). However, if you wanted to submit a pull request that makes it possible for handlers to return specific error details that should be returned to the client, that would make sense. One way of doing this would be to have a specific exception type that handlers can throw in order to ensure a message gets returned to the client; alternatively, I could see this being implemented as a return parameter of the PrepareHandleForm method. You may want to create a new GitHub issue to discuss the various ways to implement that if you'd like to give that a shot.

Let me know if you have any questions when writing the documentation.

@Nicholas-Westby Nicholas-Westby added difficulty: easy help wanted documentation Writing documentation for the Formulate.rocks website. labels Dec 16, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
difficulty: easy documentation Writing documentation for the Formulate.rocks website. help wanted
Projects
None yet
Development

No branches or pull requests

2 participants