Closed jeffmath closed 7 years ago
If I make the above change to type of the resolve field, I run into a further issue where I am unable to successfully inject a service I have created into the function which fetches the data for one of the resolve keys,
Here I have tried to boil down my relevant code to a much simpler example:
object MyApp extends JSApp
{
def main(): Unit =
{
val module = Angular.module("app", [])
module.factory[FooServiceFactory]
module.config[StatesConfig]
}
}
class StatesConfig($stateProvider: StateProvider) extends Config
{
override def initialize(): Unit =
{
val state = State(url = "/", template = "Hello world!")
state.resolve =
Dictionary[js.Function](
"data" -> ((fooService: FooService) => fooService.foo())
)
$stateProvider.state("state1", state)
}
}
@injectable("fooService")
class FooService(http: HttpService)
{
def foo(): js.Any = { new js.Object() }
}
@injectable("fooService")
class FooServiceFactory(http: HttpService) extends Factory[FooService]
{
override def apply() = new FooService(http)
}
If I were to run this app (though I'm not sure if the above compiles) and visit the only state, I would expect from my experiences with my actual app to get an error like this in the console:
client-jsdeps.js:24141 Error: [$injector:unpr] Unknown provider: fooService$2Provider <- fooService$2
Would you know why Angular can't find FooService's provider in this case?
You were correct in assuming that the resolve
API has a wrong method signature. And it turned out that there were other methods - namely, Route.resolve
, and ModalOptions.resolve
- which shared such a problem with State.resolve
.
Interestingly, only ModalOptions.resolve
seems to allow assigning plain Scala/JS objects as its parameters directly, while all of them accepts a function with dependencies as its arguments.
However, we cannot just pass a js.Function
, because it's not possible to resolve its dependencies in Scala code, and that's why the above example won't work as expected.
Fortunately, now we have ServiceDefinition
API, which can be used to convert a Scala class to such a function, like Factory[A]
, for instance.
I just committed necessary changes to make such a usage possible, so now you can write:
class MyParameterFactory(foo: FooService) extends Factory[MyParam] {
def apply(): MyParam = ???
}
//...
state.resolve = Dictionary("myParam" -> ServiceDefinition[MyParamFactory])
Please let me know if it doesn't work. I tested basic functionalities myself, but it's hard to be thorough without working test cases.
Sorry for the very late response!
Thank you for coming up with a fix. I will try it out soon, hopefully.
Per this UI-Router doc page, shouldn't the type of the resolve field in the State trait of UIRouter.scala be js.Dictionary[js.Function], instead of js.Function?
Also. could you provide an example of populating this field as part of a State definition? Preferrably, one which employs the $transition$ object as described in this section? I'm having a terrible time trying to specify these things properly in scalajs-angular. Thanks if you can help.