{"id":14973431,"url":"https://github.com/fmauquie/react-angular","last_synced_at":"2025-10-27T01:30:39.819Z","repository":{"id":53595290,"uuid":"64765986","full_name":"fmauquie/react-angular","owner":"fmauquie","description":"Use AngularJS 1.x templates in react components","archived":false,"fork":false,"pushed_at":"2019-05-16T00:42:56.000Z","size":67,"stargazers_count":25,"open_issues_count":2,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-01T01:25:13.765Z","etag":null,"topics":["angular1","angularjs","react"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fmauquie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-02T14:54:17.000Z","updated_at":"2025-01-17T10:42:57.000Z","dependencies_parsed_at":"2022-09-16T00:00:56.185Z","dependency_job_id":null,"html_url":"https://github.com/fmauquie/react-angular","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmauquie%2Freact-angular","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmauquie%2Freact-angular/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmauquie%2Freact-angular/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmauquie%2Freact-angular/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fmauquie","download_url":"https://codeload.github.com/fmauquie/react-angular/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238418217,"owners_count":19468865,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular1","angularjs","react"],"created_at":"2024-09-24T13:48:42.492Z","updated_at":"2025-10-27T01:30:34.478Z","avatar_url":"https://github.com/fmauquie.png","language":"JavaScript","readme":"# react-angular\nUse AngularJS 1.x templates in react components\n\nWhen converting an application from Angular to React, or using React in an Angular application,\nwe usually use `ngReact` to embed our React components.\nHowever, it is then close to impossible to use existing AngularJS directives inside the React components.\n\nOr rather, it was…\n\n`ReactAngular` allows you to use AngularJS templates, directives, controllers and services inside a React component.\nIt does so by providing a React component, called `AngularTemplate`,\nto which you pass the template and controller you want to use.\n\n## Installation\n\n```sh\nnpm install react-angular\n```\n\n`ReactAngular` requires React and Angular (of course!),\nalthough it isn't materialized in dependencies.\n\nIt should work fine with React 0.14+ and Angular 1.2+,\nbut is really only tested with React 15 and Angular 1.5.\n\nOnce installed, create the `react-angular` module and add it to your module's dependencies:\n\n```js\nimport { reactAngularModule } from 'react-angular';\n\n// If you are using ngReact\nangular.module('app', [reactAngularModule(true).name])\n  // ...\n  ;\n\n// If you are NOT using ngReact\nangular.module('app', [reactAngularModule(false).name])\n  // ...\n  ;\n```\n\n## Usage\n### Rendering JSX Children\n```js\nimport React from 'react';\nimport AngularTemplate from 'react-angular';\n\nexport default function SomeComponent(props) {\n  return (\u003cAngularTemplate scope={{\n    label: props.label,\n    onClick: ($event) =\u003e console.log($event),\n  }}\u003e\n    \u003cdiv data-ng-click=\"onClick($event)\"\u003e{'{{label}}'}\u003c/div\u003e\n  \u003c/AngularTemplate\u003e);\n}\n```\n\nContrary to template rendering, `AngularTemplate` will _not_ wrap your child into a wrapper `div`.\n\nThere can only be one child to `AngularTemplate`.\n\nOnce the template is rendered, `AngularTemplate` will leave the control to AngularJS for DOM updates.\nProps updates will _not_ be applied.\n\nThe AngularJS application must already be started\n(Angular module must be defined and `ng-app` must be present on a parent element).\n\nThere are a number of React rendering gotchas you must be aware of when using JSX to render AngularJS templates:\n- Angular's `{{}}` expression syntax has meaning in JSX.\n  The easiest way to use an expression is to pass a string with the expression in it\n  (like in the example above: `{'{{label}}'}`).\n- React will treat an HTML tag with a dash in it (like a _lot_ of directives) to be custom components.\n  On custom components attributes transformation does not happen, e.g.:\n  - `className` should be written `class` again (this is important: `className` will _not_ work)\n  - There is no need to prefix custom attributes with `data-`\n- Do not try to reference the first child with `ref`. `AngularTemplate` will 'steal' the reference.\n  Instead reference `AngularTemplate` and access the first child through `$element` (see API below).\n\n### Rendering a Template\n```js\nimport React from 'react';\nimport AngularTemplate from 'react-angular';\n\nimport styles from './someStyles.css';\nimport template from './someTemplate.[pug,jade,html]';\nimport controller from './someController';\n\nexport default function SomeComponent(props) {\n  return \u003cAngularTemplate\n    className={styles.wrapper}\n    template={template}\n    controller={controller}\n    controllerAs=\"ctl\"\n    inject={props}/\u003e\n}\n```\n\n`AngularTemplate` will render the AngularJS template in a wrapper `div`.\nThe wrapper `div` is fully customizable (see Advanced Usage below).\n\nOnce the template is rendered, `AngularTemplate` will leave the control to AngularJS for DOM updates.\nProps updates will _not_ be applied.\n\nThe AngularJS application must already be started\n(Angular module must be defined and `ng-app` must be present on a parent element).\n\n## Running in production\nIn production you should be using `$compileProvider.debugInfoEnabled(false);` as explained in AngularJS documentation.\n\nThis may break AngularTemplate, so you need to test it before shipping!\n\nIf you're using `ngReact` to embed React components in AngularJS,\nand declared it when adding the react-angular module to your dependencies,\nyou do not need to worry: react-angular takes care of ensuring it has everything it needs.\n\nIf you are using `ReactDOM.render()` in a custom directive, you need to wrap your React root component in a HOC\nand provide the directive scope to it:\n\n```js\nimport { provideAngularScopeHOC } from 'react-angular';\nimport { MyRootComponent } from './MyRootComponent';\n\nconst MyRootComponentWithScope = provideAngularScopeHOC(MyRootComponent);\n\nangular.module('my-module', [])\n  .directive('myDirective', () =\u003e ($scope, $element) =\u003e {\n      ReactDOM.render(\u003cMyRootComponent prop1=\"toto\" $scope={$scope} /\u003e, $element[0]);\n      // -- OR --\n      ReactDOM.render(React.createElement(MyRootComponent, { prop1: 'toto', $scope }), $element[0]);\n  });\n```\n\nIf none of those solutions work, you will need to manually add the Angular scope in a parent element of your React code.\nYou can wrap a directive linking function into a call to `ensureScopeAvailable()` to do so:\n\n```js\nimport { ensureScopeAvailable } from 'react-angular';\n\nangular.module('my-module', [])\n  .directive('myDirective', () =\u003e ({\n    ...someDirectiveDefinition,\n    link: ensureScopeAvailable(function ($scope, $element, $attrs) {\n       // Do some stuff with your directive \n    }),\n  }))\n  // -- OR use it standalone:\n  .directive('exposeScope', () =\u003e ensureScopeAvailable())\n;\n```\n\nThe `AngularTemplate` directive will complain in development that you should be careful.\nWhen you have made sure you _are_ indeed careful,\nyou can suppress this warning by adding the following snippet in your Angular module:\n\n```js\nangular.module('app', [reactAngularModule(false).name])\n  .run((reactAngularProductionReady) =\u003e reactAngularProductionReady())\n  ;\n```\n\n## Basic Props\n\n### className: `String`\nThe class to apply to the wrapper `div`.\n\nThis allows you to control how the wrapper (and the directive inside it) is displayed in your page.\n\nThis class will be added to the child JSX element if you're using JSX templates,\nin addition to any class defined on the child itself.\n\n### controller: `String|Function`\nThe controller to apply to the template. This is a definition of a controller as in any AngularJS template or route.\n\nThis may be:\n- A controller name (`String`): The controller will be found in the controllers declared in the AngularJS application\n- A controller constructor (`Function`): The controller constructor will be used as-is.\n- A \"controllerAs\" expression (`String`): The controller will be instantiated from the AngularJS application and bound to the scope.\n\nController will be injected with the scope,\nthe wrapper element,\nthe services defined in the application\nand all properties defined in the `inject` prop.\n\n### controllerAs: `String`\nBind the controller to a variable in the scope. This is like the `controllerAs` parameter in route definitions.\n\nThis is the preferred way to bind a controller to a template.\nAn alternative is to use the \"controllerAs\" syntax in the `controller` prop.\n\n### inject: `Object`\nA key-value pair of data to inject into the controller.\n\nIf the template is a function (e.g. a Pug/Jade template), the values defined here will also be passed to the template function.\n\nExample:\n\n`controller.js`:\n```js\n/* @ngInject */\nexport default function MyController($document, someClass) {\n  this.hasClass = $document.find('body').hasClass(someClass);\n}\n```\n`MyComponent.jsx`:\n```js\nimport React from 'react';\nimport AngularTemplate from 'react-angular';\n\nimport controler from './controller';\n\nexport default function MyComponent(props) {\n  return \u003cAngularTemplate\n    template=\"\u003cdiv ng-class='{ active: doc.hasClass }'\u003e\u003c/div\u003e\"\n    controller={controller}\n    controllerAs=\"doc\"\n    inject={{\n      someClass: 'document-active',\n    }}\n  /\u003e;\n}\n```\n\n### isolate: `Boolean`\nCreate an isolate scope instead of a normal scope.\n\nYou may use this to enforce component isolation at the AngularJS level.\n\n### scope: `Boolean|Object`\nShould a scope be created for the wrapper element ?\n\nBy default a scope will be created. You can prevent this by passing `false` to this prop.\n\nYou should not pass `false` if you are using a controller.\n\nIf you pass an object, any value in the object will be copied to the created scope.\n\nExample:\n```js\nimport React from 'react';\nimport AngularTemplate from 'react-angular';\n\nexport default function MyComponent(props) {\n  return \u003cAngularTemplate\n    template=\"\u003cdiv ng-bind='someValue'\u003e\u003c/div\u003e\"\n    scope={{\n      someValue: props.value || 'unknown',\n    }}\n  /\u003e;\n}\n```\n\n### template: `String|Function`\nThe template to use.\n\nYou can specify a string (loaded from HTML or directly in the prop),\nor a function (generated in JS or a Pug/Jade import).\n\nIf you specify a function, the object provided in `inject` will be passed as the first argument.\n\nIf both `template` and `templateUrl` are specified, `template` will be used.\n\nYou should not use `template` when using JSX children.\nIf you choose to do it anyway, the template will be included _after_ the children.\n\n### templateUrl: `String`\nUse a template from Angular's template cache.\nThis allows you to use a template loader or template scripts as the template source.\n\nIf both `template` and `templateUrl` are specified, `template` will be used.\n\nYou should not use `templateUrl` when using JSX children.\nIf you choose to do it anyway, the template will be included _after_ the children.\n\n### wrapperTag: `String`\nThe wrapper tag to use. By default it is a `div`.\n\nYou can change it to a `span` or anything else,\neven an element directive (see Advanced Usage below).\n\n`wrapperTag` is completely ignored when using JSX children.\n\n### wrapperAttrs: `Object`\nAttributes to apply to the wrapper element.\n\nThese will be passed as in JSX, e.g. all non-standard attributes have to be prefixed with `data-`.\nNo transformation will be applied to the attributes, so they have to be passed as in HTML\n(e.g. pass `data-ng-bind`, not 'ngBind').\nOn a custom component wrapper, no transformation is applied (see Rendering JSX Children above).\n\n`wrapperAttrs` are applied to the root JSX child when using JSX children rendering.\n\n## Known Caveats and Limitations\n\n### Property flow\nSince AngularJS and React have a different approach to updating the DOM,\nproperty updates will _not_ be propagated to the managed scope or controller.\n\nYou should *never* count on Angular updating a property passed to `AngularTemplate`,\nalthough `AngularTemplate` does not do anything to prevent it.\n\nIf you want to watch scope changes, you should reference the `AngularTemplate` instance and add watchers to the scope\n(see Advanced Usage below).\n\n### Using `require()`\nSince the library is written in ES6 and transpiled with Babel,\nwhen using `require()` instead of `import` to import it,\nyou must explicitly ask for the default export:\n```js\nvar AngularTemplate = require('react-angular').default;\n```\n\n## Advanced Usage\n\n### Wrapper element\nBy manipulating the wrapper tag (`wrapperTag` and `wrapperAttrs` props),\nyou can declare attribute directives directly on the wrapper element (e.g. `data-ng-bind`),\nor even insert an element directive directly as the wrapper tag.\n\n### API\nBy referencing the `AngularTemplate` component,\nyou can get access to several component attributes that allow you to manipulate the created AngularJS structure:\n\n- `$scope`: This is the scope used to compile the wrapper tag and the template.\n  You can use this to add watchers or event handlers, or to send events.\n- `$element`: This is the wrapper element as a JQLite element.\n  You can use this to further manipulate or query the DOM.\n  When using directives that mutate the root element,\n  `$element` may not represent the actual content of the DOM since it could have been replaced, changed,\n  duplicated or removed from the DOM.\n  The API makes no attempt at keeping `$element` up-to-date with extreme and borderline manipulations.\n\nExample:\n```js\nimport React from 'react';\nimport AngularTemplate from 'react-angular';\n\nexport default class MyComponent {\n  componentDidMount() {\n    this.reactAngular.$scope.$watch(\n      'someValue',\n       (newValue) =\u003e console.log(newValue)\n     );\n  }\n\n  render() {\n    return \u003cAngularTemplate\n      ref={(reactAngular) =\u003e this.reactAngular = reactAngular}\n      template=\"\u003cdiv ng-click='someValue++'\u003e\u003c/div\u003e\"\n      scope={{\n        someValue: props.value || 'unknown',\n      }}\n    /\u003e;\n  }\n}\n```\n\n## Roadmap\n- Support for easily creating \"directive components\",\n  e.g. the inverse of ngReact's reactDirective function\n- Better doc (this one is kinda messy, although pretty much complete)\n- Support other module loaders?\n\n## Contributing\nContributions to the documentation and the code are welcome, just make a PR!\n\nRemember to contribute the test along with the feature (or the test that shows up the bug).\n\nTo run a continuous build:\n```sh\nnpm run build:watch\n```\n\nTo run continuous testing:\n```sh\nnpm run test:watch\n```\n\n## Authors and license\nThis library is licenced under the MIT licence (see LICENCE file).\n\nAuthors:\n- Fabien Mauquié\n\n## Changelog\n\nv0.4.0\n- **Breaking change** You need to add a module to your app's dependencies\n- Make sure we can get a module in production mode with `ngReact`, independently of loading order\n\nv0.3.1\n- Fix usage without `ngReact`\n- Fix exposing HOC and directive link decorator\n\nv0.3.0\n- Allow running with `$compileProvider.debugInfoEnabled(false);` with `ngReact`, a HOC, or a custom directive\n- Document production mode\n- Use `prop-types` package\n\nv0.2.0\n- Change directive name to `AngularTemplate` (better readability)\n- JSX children rendering\n\nv0.1.0\n- Initial version\n- ReactAngular component\n- Template rendering\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmauquie%2Freact-angular","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffmauquie%2Freact-angular","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmauquie%2Freact-angular/lists"}