DEV Community

Maksym Parfenov
Maksym Parfenov

Posted on

How to add React to Angular app with PubSub.

Image description

Many people face an issue when receiving some task when need to update an Angular application but the designer provides new elements which u already implemented in some React components or applications. And last time when u opened the app was 1 year ago or never and the app was made by another person who left the company.

If you will decide to integrate React to Angular by instructions that you will find on google, you will pass all these steps on this chart:

Image description

But, maybe, you don’t need to pass all these steps and rewrite or copy-paste components and styles and do research documentation because also Angular version updated for the last 2 months up 2 times.

Motivation
If you will try to do some research, on what google may offer to you, you will be screaming like a little girl, because you will have to the special wrapper for an Angular app for each component that represents or uses a React component and u still had a question, what if I have a whole react-components npm package and I don’t want to do this and it looks like, I will be fired before I will finish this feature.

So, I have good news for you, If u cannot find a new job without Angular or your salary is good enough for the current position, you can use my tips, and maybe I can help u with your pain.

Why I am hating Angular
I don’t, really, but each time I’m trying to use Angular, it is always about 1 task or my manager expects quick integration. Because, when we are saying scalable projects or reusable components, they think ‘we don’t pay twice for the same job’, ok, but he won’t be sitting on documentation of Angular, he won’t be working at night.

Example
let’s imagine, we have an Angular app and we want to integrate Modal. A simple example is that modals we can do separately. But the button, which will invoke the modal is on the Angular side.

What we need before will start to cook

  1. React app 10+
  2. Angular app 2+ ( for <2 version, we have like react2angular or wise versa )
  3. PubSub event module ( or create your own, we need subscribe, publish functions for simple implementation )

PubSub module
We need to install it globally for both projects, for example we can use cdn link in our global Angular HTML before angular/react scripts

<script src="https://cdnjs.cloudflare.com/ajax/libs/pubsub-js/1.5.8/pubsub.min.js"></script>
Enter fullscreen mode Exit fullscreen mode

alright, we can take the PubSub variable globally in our project.

The Angular app
For Angular, we have top bar navigation, left bar navigation, whatever, some function where we’re invoking open modal, and we did it on the Angular side with Angular components.

We need to use our global level variable PubSub and invoke publish function, which means, that every listener on this function will be invoked. Like the onClick function that we add everywhere when we want to do some action on this click.

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  sendEvent() {
     PubSub.publish("send-event-to-react");
  }
}
Enter fullscreen mode Exit fullscreen mode

Alright, we are sending some event, when we’re invoking this sendEvent function. But where are we listening?

The React app
In the React application, we can use such a listener to our event from the Angular app and do it. In my example, I’m invoking the native browser modal.

PubSub.subscribe("send-event-to-react", () => {
  alert("I am modal from react")
});
Enter fullscreen mode Exit fullscreen mode

I prepared for you a more hard example with sandbox, where u can play with two buttons, first one will be from Angular that sends an event and shows a button on the React side, and React button will be sending an event to the Angular app. It’s how u can communicate because u can send not only events but also data. An array of IDs, categories, whatever u need.

Is it a joke, events, really?

Image description

Not only events, but we also have a React Portal, to make it integrated as HTML into Angular layout. But yes, for simple features, modals, separate pages, sections, menu, and notifications u can use only events and it's a really simple solution.

How can I send objects/arrays between React and Angular?

PubSub.pusblish('EVENT-NAME', {a:1}/[1])
PubSub.subscribe('EVENT-NAME', (object/array) => console.log(object or array)
Enter fullscreen mode Exit fullscreen mode

Micro frontends
Originally this solution with events is a micro frontends pattern or architecture, u can find even frameworks for this, but why do u need this, if Angular is already a huge framework. In case u need to use it, I think because of the shared state, for example, React has a Redux and Angular has some too, how to combine it, so frameworks will help u. But don’t think it is the easiest way, rather pass an object/array to Angular through events or vice versa.

The architecture with micro frontends is about also shared state management or auth or whatever, but u forgot, that our goal is to make a manager happy and don’t learn Angular 😄. And sure, it’s a step to refactoring. Because u can step by step remove components that are written with the Angular framework.

Live example

Here u can find additional code and information, try this. It is an Angular application and integrated React application without npm modules. You should have a separate bundle, which means 2 js, first one is Angular and the second one is React, so u should have 1 HTML where u will put ur JS builds and it will be working.

By default React app from create-react-app npm tool will create for server tool that will serve the content, u need to do inject and replace configuration or run separately, for example, npm run start will do serve and separate page for the React only and npm run start:bundle will expose for u a link to the js bundle.

Let me know, maybe I will cover this case with a Webpack configuration in a separate article.

index.html


<div id="react-root"></div>
<script
src="https://unpkg.com/react@18/umd/react.development.js"
crossorigin
></script>
<script
src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
crossorigin
></script>
<script crossorigin src="./react-component.js"></script>
Enter fullscreen mode Exit fullscreen mode

In my source, u can find this code, it is just integration to make sure u will try it in the sandbox, in your case, u don’t need this, u have to add react bundle, 1 URL, and 1 div “react-root” like in my example and it will be working for u.

<app-root></app-root>
Enter fullscreen mode Exit fullscreen mode

app-root needed for Angular part, it is like a div with id app-root, in the Sandbox u won’t find the Angular sources, because they render it differently

Add React component to Angular with React Portal
Technically, if u have a div with some id, u can use React Portal and insert your React code to the Angular view. It should work, I didn’t try yet, because I decided to not implement it on React side. I just made a fix like this 😢.

.react-fixed-button {
   position: fixed;
   top: 0;
   left: 0;
}
Enter fullscreen mode Exit fullscreen mode

And because it was a scrollable menu on the top, it worked for me perfectly, but u can also try React Portal, maybe I will cover this case in my next article.

Top comments (0)