Dont wanna be the boo man here but one of your i18n related unit tests failed for me when i cloned your repo. Guess its because of different timezones.
Haha yeah I had some date check failed at some point on CircleCI, which I donāt know what TZ they use. I might have hacked a test or two just to get it going on CircleCI. The date TZ stuff are not really big tests that I care. Anywho, you can maybe tell me which test that is and I can take a look to see if I can tweak it, thanks.
Iām on the Eastern TimeZone (North America) and I know youāre on a different TZ.
I think all youād need to do for the tests is to fix the tz like here https://github.com/aurelia/i18n/blob/master/test/unit/dfvalueconverter.spec.ts#L64
You canāt ānewā arrow function. It probably works with Jest because it was transpiled to ES5.
Just in case you hit it in the future
@bigopon
My Jest unit tests are all written in TypeScript, so I usually do it with the arrow function since the linter will complain if I donāt.
I have another issue though, I looked at your sandbox again and I understand how to have a global and a local instance of the Event Aggregator but how do I get access to the global one from my Services and from the Pagination child component? I have a few subscribed events when the I18N locale changed, and now they are all broken except for the ones that are in the parent component, for example the grid column headers are being translated because the code is in the parent component but the ones in the pagination component are no longer being translated because the injected EA is the local EA one. Is there a way to alias that or something? in the sandbox you did name it parent_not_global_Ea
in the child component.
EDIT
After some digging in the Aurelia-I18N lib, I found that we can have access to itās internal EA directly from the I18N Service with this.i18n.ea.subscribe('i18n:locale:changed', () => {})
and that will do it for my usage.
I still would like to know how to access both Global DI from Services or Child Component, but at least now I can work around it.
May I know why aliasing with NewInstance.of().as
didnāt work for you? Itās working for me here https://codesandbox.io/s/httpsdiscourseaureliaiothow-to-use-event-aggregator-as-transient-with-custom-element3181-o3e2b
Thanks, I did see the NewInstance.of().as()
in the docs but I couldnāt find any examples in the docs neither online and the d.ts
didnāt help either. When I tried it, I thought it was a string name aliasing as('string')
but that didnāt work. I see you updated the sandbox and now I understand how to use it, it would help so much to have this in the docs. Does the aliased class have to have all the methods? Because I donāt see SlickgridEa
being extended from EventAggregator
and itās missing the dispose
, does it have to be defined or that doesnāt matter?
Thanks again
The purpose of alias is to alter the key required to retrieve an instance.
In this case, the flow is like this:
- we want to retrieve an instance of
EventAggregator
,EventAggregator
was used to inject the instance inChild
via@inject(EventAggregator)
- we want to scope an
EventAggregator
per instance ofParent
, so we useNewInstance.of(EventAggregator)
- we want to avoid scoping issue, since only
Child
wishes to get the scopedEventAggregator
instance, while otherChild_x
s donāt. so we need another way to retrieve it without blocking others. - We used
NewInstance.of().As(SlickGridEa)
to scopeEventAggregator
and make it only retrievable via the aliasSlickGridEa
(https://github.com/aurelia/dependency-injection/blob/191d7d68cd0271a985178e770dd6b64d8cf9c418/src/resolvers.ts#L439). SoSlickGridEa
is basically is just a key to get our scopedEventAggregator
instance, and provides strict typing for event name. What constructor that will actually be invoked is theEventAggregator
Thanks again, Iām starting to see the power of these DI wording. I rewrote all of my Services and Custom Elements to now use whichever I need and when I want both I now have
@inject(EventAggregator, SlickgridEventAggregator)
export MyClass {
constructor(private globalEa: EventAggregator, private pluginEa: SlickgridEventAggregator) {}
This is powerful and awesome!
Now I have yet another question, how do we extend the Event Aggregator from the at alias? This is following a new issue that Iāve opened today in the Event Aggregator lib (this issue) which Rob replied here that I should extend the EA class
I tried changing the absctract class that you provided and change it into an extended class of the Event Aggregator but that doesnāt seem to work.
export class SlickgridEventAggregator extends EventAggregator {
constructor() {
super();
}
publish(event: string, data: any): void {
// do something before calling super
super.publish(event, data);
}
subscribe(event: string, callback: (data: any) => void): Disposable {
// do something before calling super
return super.subscribe(event, callback);
}
}
I added a bunch of console log and nothing shows up, is that supposed to be only an abstract interface that I canāt extend? Sorry about all of these questions, I feel like I still have a lot to learn.
Probably because of what you wrote in previous post?
SlickGridEa
is basically is just a key to get our scopedEventAggregator
instance, and provides strict typing for event name. What constructor that will actually be invoked is theEventAggregator
If you extended jt, then you can use the subclass as the key, or just inject the subclass. The only reason we went for aliasing was because we wanted to avoid conflict. Since you already have your own internal key (subclass), theres no need to do anything extra
Ok I was confused at first, but I think I understand now and that make sense, so if I understood correctly then you mean to change NewInstance.of(EventAggregator).as(SlickgridEventAggregator)
into this NewInstance.of(SlickgridEventAggregator)
and thereās no need for alias since the class name is now unique. I tried it and that seems to work, so I think Iām finally good now.
Thanks for everything, really appreciate your time in helping others like me
Iām glad we had this discussion, as we can finally have a Q/A topic that demonstrates:
- how to scope a class to your plugin custom element
- how to extend event aggregator and do your custom stuff (Non-existence, can you doc it here or somewhere please, my turn to ask for help )
btw, if your constructor only call super then probably you donāt need it
Ahh really, I thought it was required to call the super constructor so that it instantiate the class. I didnāt know we could go without it. I removed it like you said and pasted the remaining code in the issue I had previously opened.
Hmm Iām not sure if Iām the right person to explain it in docs, but I can try to help a bit yeah since you provided me lot of good information. What did you have in mind? Would that be to extend on this doc or something else? Iām not even sure where the docs code is.
I do like the flow that we followed together, we covered lot of good stuff with DI and Event Aggregator, that certain flow might be explainable in a doc as a sample.
Yes, that section would be very useful, and our chat will be a very nice example for that
Hello @bigopon, Iām not sure if this is what you wanted but I spent an hour writing this Event Aggregator - Use Cases Wiki. It has 4 unit cases, which were all related to our conversation. Iāve created the Wiki under my Aurelia-Slickgrid lib, just for a placeholder, you can also edit the Wiki if you wish to adjust some of the text. Is that what you were looking for? I donāt think I used all the correct wording, so feel free to update.
Nice, looks pretty good to me. I was asking fornhelp with our official docnbut i guess that will do, i probably need to bookmark this for later to show as exmple for other similar Qs
Thanks, it might be lengthy for a docā¦ however the fact is that itās the kind of doc I like to read, with brief use cases and some code samples to demo them.
Also just to provide more details about the kind of docs that I like to read, MDN (which is now used in VSCode intellisense for any html/css selector), they have wonderful docs that are super easy to understand with enough details, for instance see Array.prototype.filter(). They provide a set of use cases that are easy to understand, I see a lot of Stack Overflow references to their docs as well. They have the best docs Iāve seen
in Aurelia we can find this tutorial adding pub/sub messaging which is similar in some ways, however I donāt think we need to provide a full and lengthy story. I would prefer to see docs like MDN and/or like the one I wrote. That would be easier to search and follow.
Yes, I your observation & conclusion is on point. That is probably could be a lot better for us. Tons of example in every corner
Looping @EisenbergEffect into this