AngularJS is Dead. Long live Open AI! A migration miracle.

Júlio Almeida
8 min readJan 12, 2022

--

Angular JS has officially reached end-of-life (EOL) status. This was something that everyone in the front-end community expected since the existence of “Angular” has been a bumpy road. AngularJS appeared in the scene in 2010, to be “replaced” just 6 years later by Angular 2, a much better Framework. If this is not troubling enough, Angular has been losing market share continuously since the beginning of the pandemic to React and Vue.

Migration and another JS Framework

I would consider this one of those greatest “Double-Edged Swords” of the software development ecosystem, more specifically in the front-end. Pieces of software (libraries, frameworks, you name it) come and go, but the invested codebase stays. This problem is so widely known, that any experienced developer had to do it. Not migrating legacy code that is being iterated on a regular basis will result in comfortable developers, or worse, no new great talent will join you. The problem has become so big that nowadays you should keep your stack “tech-savvy” just to attract the right talent.

This is pretty and such but costs a fortune and there is no real added value to the client.

Open AI: to the rescue

In the last year, I was contacted at least 3 times about this problem. People trying to migrate everything all together, or simply keep the old and start the new from Scratch, using micro-frontends. I proposed a couple of times using Open AI codex to give a boost but the answer was always “it was bad anyway, we want to rewrite it”. But the time has finally come, at least for me to try it. This story is actually the way I'm approaching the problem in an easy and public format.

Open AI is exposed pragmatically as possible (too pragmatic though) with four main endpoints: Completions, Searches, Classifications, and Answers. Let's focus on Completions[1]:

This is an example of the request. The only thing important for this article is really the property prompt, which will be the body of the request and the stop array, that is used to mark where the completion should stop or start.

We can use this example to start tweaking:

https://beta.openai.com/playground/p/default-translate-code?model=davinci-codex

We are going to use the playground here, but in a real-world example, some files are just too big for the token limits. Other things like multiple requests and files in the API will most likely be needed.

Open AI: Conversion of code

For explanation's sake, I will use AngularJS as the “old” and React as the “new” throughout this article as examples. Could be done with any other library or framework, even MVC full of server-side dependencies, to a pretty SPA app.

AngularJS and React work differently, I will not describe it under the hood, but the only thing that matters here is that AngularJS separates the JS, HMTL, and CSS. In React you do everything together (JSX ) or separate the CSS. So you need to bundle the code in order to get the right solution.

I will use this GitHub repo from gothinkster that contains enough examples to go across. Thank you for the repo!

https://github.com/gothinkster/angularjs-realworld-example-app

Here is the template:

##### Convert this AngularJS component into a React Hook component
### AngularJS component

//Code example https://github.com/gothinkster/angularjs-realworld-example-app/tree/master/src/js/home

// controller.js (keep this)

//put the contoller here

// home.html (keep this)

// put the html here

//home.css (keep this)

//put the css here

### React Hook component

//will appear here

Here is the Result:

The VS code has the EsLint and TSLint active. AngularJS is a complete framework, gives you tools like rooting and state management, React does not, is just a render library (not anymore but let's keep it simple). So the Open AI chose to get the industry-standard libraries for routing (react-dom) and state management (Redux). You should be impressed and scared if you ask me. The imports look as impressive as the previous ones because he got the redux architecture right by adding the actions folder. The components are also ok. Created a nice Hook component, with Dispatch, Selectors, as well the history from the react-router v6. The only thing that I don't agree with is really the useState with an object, I would separate them.

Getting the data is my favorite part if you ask me, I probably wouldn't do as good of a job at first if it was me doing this by hand. All the logic became encapsulated in the Redux actions, as it should be. The changeList function that was a broadcast event, is now a setListConfig with a Dispatch call. Nice!

Now, the mistakes. two classNames were added, what is wrong. What should be done in this situation, is to create a style attribute for these behaviors (if it is something simple), or interpolation of strings to pass the two css classes would also work.

The rest of the mistakes that we can point out is TS stuff, like not declaring types. Another nice and sloppy one is the attempt to create a new component by abstraction but ended up adding the code anyway. You can see the unused references that I commented as “ok”.

Just to end, you can really see the machine signature at lines 33 and 44 :).

Now, I took the worst-case scenario, and you should not do this. The image below is a good way to struct the workflow.

Workflow of conversion of Angular to React

The Open AI will be smart enough to convert AngularJS components to React components in JSX, but if anything goes wrong in the passage of the props, will be easy to test. So make sure that the simpler ones work as expected instead of trying to do everything at once.

Open AI: App Services

Now let's see how to approach services. Here is the template:

##### Convert this AngularJS Service component into a Service without AngularJS and with Axios, async/await and Promises and Typescript
### AngularJS Service
//code goes here (
https://github.com/gothinkster/angularjs-realworld-example-app/blob/master/src/js/services/profile.service.js)
### Service without AngularJS and with Axios, async/await and Promises and Typescript

In AngularJS you have dependency injection in a class. In React you could simply use a simple export const that gets everything from a scoped configuration (e.g Webpack config). Sometimes you need to give the engine a little push, and here is no different. If you just copy/paste you will get an AngularJS mixture. The two approaches below:

No help (left) vs with help (right)

Using the template above, we can see a lot of good things. Axios is imported, async/await is added flawlessly, string interpolation appears, but in the left, we can see that he keeps the AngularJS constructor and patterns. To solve this problem, give it a little context from the start, and as you can see on the right, that problem is solved. Some limitations stay though, I said to put some TypeScript, that you will not spot, and a global variable called AppConstants, that should contain the global constants. Nothing of this is a big deal, works great regardless, but for precise results, see the section Fine-tuning.

Real Life Migration approach

This is good and such, but this only works with good planning and engineering. I will not focus here on what kind of Micro-frontend framework is best, or if it is SPA, MVC, Server Side Rendering, or any other design pattern or architecture. The only focus is to save costs and the precious time of the senior devs. So this is the client situation:

  • Precious seniors cannot be used for the migration.
  • Should be done parallelly with the other development.
  • Should not present any type of roadblock when switching views.
  • Can we pay a junior to try it out?

I of course “embellish” the bullet points above, in order to create a best-case scenario regarding ROI.

Let´s look at an example:

Micro-frontend architecture

In the image above we have 3 legacy (Angular) views, and 2 new (React) views on top of a Micro-frontend framework. I will continue to use the names of the frameworks/libraries for simplifications reasons. This is how it should be done:

  1. Get a developer with React experience. The ability to write JS/TS should be enough to understand the old business logic or any other that permeates the code.
  2. Build the Micro-frontend infrastructure. This should be the routing, log in and others of that nature. Some middlewares and brokers maybe will be needed, for example for state management (once again, it really depends on what you are using).
  3. Start with the view that doesn't change. Test it and switch it.

Pretty basic. How fast it goes will pretty much depend on the ability of the Open AI to convert from old to new. When the framework is similar and the code is well built, the AI will be able to keep a good grasp of the context and convert in an almost “miraculous” way. If you make month progress in just a day and get stuck in a component for days because the Open AI is useless, don't be surprised, it will happen.

Fine-tuning. Next level of illumination

This is an advanced feature, that is not needed, but could be useful for the reader in the future [2]. You can train the Open AI in order to create your “superset” model if you will. I didn’t use it for this situation, but I'm using it internally. One more image, because I'm a visual person and it's pretty:

Training a new model

The image above is as simple as the training process follows. Like any other AI, training a model is more an art than anything else. Firstly, you need to build your JSONL [3] files, since it is format consumed. You have a conversion tool to help you out. On the prompt you have the old code, on the completion, you have the new code. Build the model and try to use it.

This could be of course could be a business idea to be explored. If you are imagining a website drag and drop that magically converts to a new version, get off your high horse, it's close to impossible, but works great using this consulting/contractor approach. Maybe with GTP-4, I don't know.

Conclusion

What I like about Open AI is that if you are creative and clever enough, you will find use cases. This one allowed me to present a solution to a client with a great ROI in mind, as well convert old react code, class to hooks, in a matter of seconds, and he will make fewer mistakes than you :).

I'm open to trying this for you dear reader! Thank you for your time!

--

--

Júlio Almeida

Creator of ExtractThinker | Contractor - Focused on extraction in enterprise | Fintech and Legal. https://www.linkedin.com/in/j%C3%BAlio-almeida-21772a125