-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: replace $resource in angularjs form-api.client.factory.js with typescript FormService #1947
Conversation
@mantariksh @chowyiyin Thanks for working on this - I'm thinking it could help with the React migration to also take a look at organising the different services better - |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a tough one to disentangle, great job!
When thinking about the implementation of the services, our first priority is to ensure that they are reusable in React. The point of the frontend services migration is to maximise the amount of code which is battle-tested in production in order to minimise the risk of the final cutover to React.
The FormService is currently doing quite a lot: injecting/stripping MyInfo data, converting POJOs into classes, handling error redirects etc. The issue with this is that it's entirely possible that we will handle all these things completely differently in React. For example, it's unlikely that we will port over the existing viewmodel classes (e.g. Form.class.js
) into React.
I think a better approach might be to make the service dumb - it takes in the relevant data to call the correct endpoint, and returns the response. That's it. Any additional formatting of the request and response must be done by the caller. Then in the existing AngularJS FormAPI service, we perform all the necessary transformations on the request and response before and after calling the new TypeScript service. This way we can be sure that the new service is reusable - it's completely framework-agnostic as it only makes API calls.
src/public/modules/forms/admin/controllers/list-forms.client.controller.js
Outdated
Show resolved
Hide resolved
src/public/modules/forms/admin/controllers/admin-form.client.controller.js
Outdated
Show resolved
Hide resolved
Thank you! :)
Do correct me if I am wrong, but I think this service is, in a way, framework agnostic since the things mentioned above (e.g. injecting and stripping MyInfo data) are actually handled in the interceptor? |
This is true! But the reasons for needing interceptors are not framework-agnostic, eg the fact that a Form POJO has to be converted into a Form class. This reflects itself in the code too, e.g. in how the Furthermore, if the service just trusts the interceptors passed to it, then ultimately the caller has to implement the interceptor correctly, meaning there isn't much value in terms of code reuse. |
Agree with @mantariksh on scoping the service to calling the correct API and returning the response - I think this is also consistent with how we've written the other services! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
first round of review, let's address these first before the next round!
src/public/modules/forms/admin/controllers/collaborator-modal.client.controller.js
Show resolved
Hide resolved
Blocked by #2061 |
9174626
to
8837971
Compare
…essage in collaborators client controller
f962176
to
b2994ff
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, really well done! let's test this super thoroughly on staging because it touches nearly every single important API. you can add the following checks to your manual tests:
- myinfo fields are correctly stripped and injected when creating myinfo fields
- myinfo fields are correctly stripped and injected when duplicating myinfo fields
- myinfo fields are correctly stripped and injected when duplicating a form with myinfo fields
- myinfo fields are correctly injected into public form view
- forms can be created from the examples page
- forms can be created from the "Share Template" link under the "Share" tab
FormErrorService.redirect({ | ||
response: err.response, | ||
targetState: errorTargetState, | ||
targetFormId: extractFormId(get(err.response, 'config.url')), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually think the current implementation of extractFormId
is wrong because we don't always have the form ID at the start of the path, but that can be fixed separately
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the thorough testing! I know it's a lot of work but I hope the importance is clear, since this PR touches a lot of core functionality.
Problem
This PR replaces the
$resource
object inform-api.client.factory.js
with API call services provided byFormService.ts
. Due to coupling between the interceptors andform-fields.client.factory
, interceptors are kept intact inform-api.client.factory.js
. Previously, theaccessMode
query parameter was also added to all API calls. This migration removes this from any API calls in which it is irrelevant.Closes #1835, #1768
Solution
getInterceptor
is called inform-api.client.factory.js
and the relevant interceptor is passed to functions inFormService.ts
, that handle all API calls.Tests
Unit Tests
FormService.test.ts
: add unit tests for functions inFormService.ts
Manual Tests
open in new window
in share tab without activating form. Should be redirected to error page. (getPublic)open in new window
in share tab after activating form. Should be redirected to public view of form. (getPublic)