-
Notifications
You must be signed in to change notification settings - Fork 34
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
Integrate e-mission and itinerum (finally!) #643
Comments
@kafitz one thing that we are still missing is displaying the survey after we retrieve it. Do you have a javascript library to do that (maybe for a preview in the survey builder)? could you add the link here as well? |
This is something I meant to ask about this on our call today, so far that's been handled by the native mobile Itinerum apps. Currently we can see and edit the questions using the existing dashboard, but the client view for e-mission would still need to be built. Is the best way to write some HTML/JS viewer now that could eventually be merged into the e-mission app? It might take a week or so (for a prototype), but seems doable relatively quickly. |
@kafitz yes, a HTML+JS viewer that would be merged with the e-mission app would be the way to go. I was assuming you would have such a viewer anyway as part of the survey builder to preview the survey as it was being built. How do survey users preview the survey right now? |
Currently we rely on the Survey Builder wizard for laying out questions and then the admin users test how it looks by running the app. If any survey questions must be fixed, it does mean they have to clear the app data and retry. The builder provides a decent enough overview for this, but it's written in React. Since the app is Cordova/Angular (which I'm still not super familiar with), I was thinking now I can create a very simple interface with HTML & vanilla JS and this will hopefully keep it easy to merge into the e-mission-phone code later. Open to suggestions ofc if there's a better way to do it. I'll admit I'm slightly worried about it snowballing, but I think it should be ok if we don't worry about aesthetics until putting it into the app. |
so I've been poking around with the edges of react for a while (https://github.com/NREL/mobility_landscapeapp is in React, for example), and it looks like you can use some form of react embedded into other applications. I can play around with it a bit more; if it works it seems like it would be the easiest option without introducing additional codebases that need to be maintained. It would also give us a more gradual migration path forward - as we cleanup individual components, we can rewrite them in react. Is there a simple but meaningful react component that you can share which I can use to experiment with this approach? |
This looks super simple, for example And this: Although it is currently archived |
The Tutorial.jsx snippet on this gist page is my most basic component for the help screen users first see in the dashboard. I can send a more involved example, but that may take a bit since I rewrote the codebase using Typescript/Material UI. That code resembles something closer to React Native and requires some webpack transpiling... For anything that would go in e-mission, I would still write that in regular React for simplicity. |
I think we can get webpack transpiling if we need to as well. But let's start with seeing if I can embed this first. |
@kafitz can you add a link to the API that we can use to pull the survey JSON (I assume this is on a staging server, and there is one canonical server we can pull). we can then start with reading that. At tomorrow's meeting, let's discuss at what stage on the onboarding process we should make this call and how the user specifies the survey to pull. |
to give some additional context: e-mission is currently written in angular1 also called angularJS on the internet. It is also a reactive framework in which you make changes to So concretely, if I want to display a username, I can have
then if the javascript has |
once we get the survey JSON from itinerum, we want to display it. @kafitz already has code to display it that is written in React, which is a very similar-looking but different javascript framework. So we are going to try to package the react code as a component and include it in the angular framework. The comments above claim it can be done. If not, we may have to rewrite parsing + display logic in angular. So if everything works, we will use react to create a new component called
|
The base url for the staging server will be at: https://api.hungry.wales/mobile/v2 Attached below is a shortened version of an integration testing script which includes two functions: one to make the initial API call for the survey JSON and one to POST the answers. I recently started adding some Swagger docs which may give some idea of the requests, but there's a lot more work to do on that to make it clear: https://api.hungry.wales/mobile/swagger/index.html Something to note is this would be the app to use my "v2" API which was built with conditional question logic in mind. It's backwards compatible with v1 (used by existing mobile apps), but you'll find the Demo code: emission-integration-demo.zip |
Also I would say that the client-side React code is about 50% there. We have a question builder interface which parses the JSON and maps each question to components, but it will need transformed into a client version. This I was planning to help write for the UI integration, but haven't yet ruled out Angular here if that winds up making more sense. |
I believe that there is no auth required for the initial call for the survey, how do we authenticate to POST the answers? |
To clarify about the requests for retrieving the survey, there will be two POST requests:
|
Just to clarify how this would work on the e-mission side, because of our legacy of authenticating via email, we actually generate a random token first and "register" with the server, similar to step 1 in your case. @jruzekowicz the code to currently launch the survey with a UUID is at It is invoked from https://github.com/e-mission/e-mission-phone/blob/ceo_ebike_project/www/js/intro.js#L112 for a google form and from https://github.com/e-mission/e-mission-phone/blob/nrel_location_history/www/js/intro.js#L144 for a kobo toolbox form I would suggest that an initial task would be:
|
e-mission allows you to launch a survey on an end of trip prompt, but the general feedback we have gotten is that end of trip prompts are really intrusive. So if deployments do want to have an end of trip prompt, right now, the default is to go to the diary screen where you can look at the trip and answer any "labeling" questions. That label can launch a survey, but people can wait until the end of the day to do it. Most deployments have actually switched to once a day prompts, in the evening, that just launch the diary. |
you would replace existing code with something like (very sketchy).
|
Looking through the various options above, there is a clear tradeoff between immediate usability and long-term migration. Concretely:
|
at this point, given the tight timeframe and importance of getting something to work, I am going to start with ngReact. Depending on how long that takes to get working, I will try out |
Starting with ngReact....
|
So it works for some version of react. Now, let's check the jsx stuff since that is what Kyle's example uses. That looks like it basically just includes |
That does not appear to work right out of the box. The failure is
It looks like
From the README, this is also "a hacky approach"
Going to spend another 10 mins on this, and then switch to the es6 + webpack example |
Aha! JSXTransformer was deprecated in the current version of ngReact uses react 15+, so it looks like the example was not updated. we can still use react and jsx without using webpack by including babel directly. babel can manually convert all jsx to js ahead of time. That approach works (see screenshot below)! We can now include jsx for sure, even if it is not super production ready. A minor caveat was that since we split the file into multiple javascript/jsx files, it ran into CORS issues. Note that loading from files doesn't work with CORS any more, so we have to start up a tiny web server. I used https://github.com/danjellesma/http-server; the same as em-dashboard and everything worked great. |
Now, let's try the "production" version of babel without going all the way to webpack and transpiling. Although perhaps we should/will get there eventually. This turned out to be a little harder than I thought, so I'm creating a fork with my changes for the part that is already working. Then I can continue noodling on the part that is not working, but in a separate directory, and with the ability to compare working and non-working side by side. |
This required minor modifications to the source code since the previous approach using the JSXTransformer is now deprecated e-mission/e-mission-docs#643 (comment) This is also not the recommended "production" version, which involves manually precompiling the JSX file. https://reactjs.org/docs/add-react-to-a-website.html#add-jsx-to-a-project Will try that next
I'm now going to try to use this itinerum example with ngReact. Then last step is to use it with e-mission-phone. |
It (sort of) works. I had to remove all the parts with @import and export because otherwise, even with the autogenerated js file, I got errors like
because the generated js file had
at the end. Similarly, for the import statements, we had
But without that, I am not sure how to include the scss |
I notice that none of the sample JSX for use with script tags, either in ngReact or in the basic react code I suspect I need to remove all the imports if we want to use the |
Looking through the ngReact code, it looks like the error is from
which is in turn called from
The part that is confusing me is that at that point, ngReact hasn't even started looking up the component. It is just seeing if the name exists or not. @kafitz can you add breakpoints or log statements to the ngReact code to figure out what is going on? Maybe something like
|
FYI, I ran with this logging enabled for only the tutorial component, and I got the following logs
So that's why it doesn't fail for the TutorialComponent; it is because it is already a function. Looking at the autogenerated
Will have to see if @kafitz's new component generates something similar. |
@kafitz I tried to compile your script using the babel command line at: I think I have all the correct versions installed (I had to guess, but got the most recent versions),
but I still get the following error.
|
Ah, based on changed the command line to
(removed |
@kafitz are you sure you are able to run with the Note that for my transpiling, I used
This used to work just fine with babel 6.x, but it fails with babel 7.x.
Going back to 6.x, it works again
You saw that I had to remove the How did you manage to get that preset to work? I want to check the output with that included. |
I was digging into the differences of the presets earlier, it looks like the babel-preset-react-app that you had includes things that are now part of the normal @babel/preset-react, so I had been experimenting with that in --plugins (I think we still need one of them). Both seem to yield similar outputs. My current package,json looks like this:
and my compilation command is:
NOTE: in version 7, i was only able to get the older The significant difference I see in the output is that function you called attention to:
My version looks like this after running babel:
and seems to be missing most of the guts from the class version. It's odd because I did find some issues threads that indicate this should be possible:
I will have to focus on some things for a few hours and will be able to resume debugging this evening. |
FYI: I got the If you remove the parts of your code that require babel 7 and run the exact same command line that I use, do you get the same class structure? if so, then we know that the problem is with babel 6 v/s babel 7 and can figure out which way to go forward. |
The issue with v6 is I didn't think Typescript had a compatible preset so I get stuck there first. |
Looks like this works with CRA |
Progress! Although I'm not entirely certain how to get Babel to fully cooperate yet...if I remove the various import/exports from my generated QuestionLayout.js, I see my "HELLO WORLD!" text.
This was generated by the babel command:
and a
|
Unfortunately there's still something causing it to break whenever I attempt to include an import from node_modules. I get the same Such as:
generating:
Continuing to investigate. |
@kafitz did you see the example with es6 and webpack (https://github.com/ngReact/ngReact/tree/master/examples/es6-tests-webpack). That does seem to have some imports e.g. https://github.com/ngReact/ngReact/blob/master/examples/es6-tests-webpack/lib/watch-list-component.js#L1 I didn't try to run that, since it didn't seem to be needed. LMK if that is closer to what you need, and I can see whether it works. |
@kafitz not sure if this helps, but I have some additional information. I basically added all the tutorial stuff back as well so I could compare the tutorial and the react components side by side. I first realized that the
I then tried accessing the variables we pass in to the directives. TutorialComponent is a function
but the react component is
do you have to do anything special to "export" the |
That example from two comments back seems to be what I'm looking for, but haven't managed it myself yet. Babel is fine when I import from a sibling file (since it generates that file .js alongside and removes the import), so I think it's generating an import/require() for the 3rd-party libraries that ngReact isn't liking. I also noticed similar regarding the reactComponentName being the full function definition, so it made me slightly more confused how my stateless component even displayed (will still have to log that and see). Generally speaking, I would a
at the top of my generated files as well as that bottom export, that's when it did seem to briefly work. |
Primarily my reservations have been having to completely re-implement my state handling and JSON logic. My original JS-only version was too messy to consider here, so this TypeScript version was a complete rewrite. So long as we can continue to use TypeScript, then it probably won't be such a big deal (just time consuming) to reformat the state components as class style ones. |
There are a couple of other things we can try. The issue that you linked to a couple of comments above said something like
So we could try the directive and see what it gives us. I would also suggest first trying to get stateless components to work with the ngReact examples, since there are code examples there and it is faster to develop directly in the browser. We can also pass the name of the component
which will trigger the alternate code path where ngReact tries to use UPDATE: Reading the I can try playing around with this on the ngReact repo over the weekend if you give me an MRE. Is that just |
I've still not gotten to the root of the issue but have committed my latest half-working state here: https://github.com/kafitz/e-mission-phone/ under the same I've just noticed that the package.json is not committed by default, so I'll include mine here for now:
The only files I've been editing are the You will see in the For compiling, my command is:
which is also in a After that, it's the normal I think part of my slowdown is not knowing how to debug off the phone so I'm often making changes, reloading em-dev and seeing if it worked. Is there a better way I should be doing it? |
@kafitz that's why I think it might be easier to work off the ngReact repo first, since there is no phone component involved. At this point, I think that if it works in ngReact, we can get it to work on the phone. I have a fork of ngReact where I have been including the prior version of your example. We could make a new directory and explore there first https://github.com/shankari/ngReact/ |
I see, I didn't think of trying to use it independently so far. So that would require having a demo Angular app that works in the browser (for now) and testing my .tsx component there first? I'll start doing that next |
the examples in ngReact already have a demo angular app. I would start by copying https://github.com/shankari/ngReact/tree/master/examples/itinerum_tutorial and going from there. |
Current status / what I've tried:
Basic Currently working on trying to combine https://github.com/ngReact/ngReact/tree/master/examples/es6-tests-webpack with create-react-app examples |
@kafitz that's great progress. @jruzekowicz is making good progress on the last part of the integration (saving to DB and pushing up to server), so might be able to help with this soon as well in case having another person trying things out in parallel would help. |
@kafitz have you made any progress on this? I might have some time this weekend to work on this, although my javascriot-fu is pretty weak |
or are you giving up on the idea of stateless components and planning to use stateful componets |
I have the stateless components working here: https://github.com/hexmap/emission-plugin-itinerum-questionnaire I worked off the ngReact es6 example using Webpack/babel, but everything at the latest versions. Most of my trouble this week was in passing my JSON schema from Angular->React, but I think I'd been unnecessarily caught up trying to emulate the Promises to keep it true to the ngReact example. This is finished, so now I'm working on merging my React dashboard code to parse and manage the survey with my Flutter version of the Itinerum mobile survey. So far no big issues on that, the next big test will be when I implement navigation between survey questions. |
The thing that finally got the stateless version to work was having this factory function: https://github.com/hexmap/emission-plugin-itinerum-questionnaire/blob/master/lib/itinerum-survey-component.tsx#L23 Why this works, however, is still a mystery. |
Itinerum is currently on hiatus. We have integrated an enketo toolbox-based survey for the initial survey |
@PatGendre @asiripanich you should be happy about this :)
@kafitz and I just had the preliminary discussion around how the integration might work.
A very basic data-level (not code-level) integration would be:
That seems eminently doable in the short internship timeframe
The text was updated successfully, but these errors were encountered: