Skip to content
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

How to inject angularjs dependencies in child react components? #91

Open
coreysnyder opened this issue Sep 17, 2018 · 1 comment
Open

Comments

@coreysnyder
Copy link

Let's say I use this library to attach a react component to a route /users.

import { react2angular } from 'react2angular';
import EditContractContainer from './EditContractContainer.jsx';
import EpisodeEditorApiMod from '../../yamsf/episode-editor';
import PayorApiMod from '../../yamsf/payer-service';
var angular = require('angular');

module.exports = angular.module('mymod.edit', [
  EpisodeEditorApiMod, PayorApiMod
])
.component('editContractContainer', react2angular(EditContractContainer, [], ['$injector']))
.config(function($stateProvider) {
  $stateProvider.state({
    name: 'EditContractContainer',
    url: '/edit-contract/:contractId',
    component: 'editContractContainer'
  });
})

.name;

And then Then that react component has it's own child components. How do those child components get access to angularjs services?

I ran into this so I came up w/ the idea to inject $injector into my parent component. Then I pass it down as props to the children. Then they can use this to pick of any angularjs services they need.

    this.$stateParams = $injector.get('$stateParams');
    this.contractService = $injector.get('contractService');

But there's a catch.. You can only inject providers which have been added as dependencies to the parent module. So that means if a downstream component wants to $inject userService, I'd have to go back up to the parent module where the react2angular component is added, and add:

import UserAPIMod from '../../yamsf/user-service';

And then add it as a requirement

module.exports = angular.module('mymod.edit', [
  EpisodeEditorApiMod, PayorApiMod, UserAPIMod
])

Is there a way around this? I really don't like it because then components have requirements on their parents. Also it's undoubtedly going to get to the point where that parent module is including a bunch of stuff its children no longer use. How would you combat this?

@cpimhoff
Copy link

Hi there! If you are comfortable with using something a bit stateful, and not varying injectors by component tree, you can do this with:

const myService = angular.element(document.body).injector().get(SERVICE_NAME);

You can even write a hook to cache this. Something like:

function useAngularInjection(name) {
  return useMemo(() => angular.element(document.body).injector().get(name), [])
}

function MyComponent(props) {
   const stateParams = useAngularInjection('$stateParams');
  return <> ... </>;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants