I'm fairly new to Typescript.
I have 2 microservices, let's call them ManagerMs and HandlerMs.
They communicate through RabbitMq.
Each of their public methods, becomes a queue on Rabbit when service starts.
The ManagerMs need to preform an RPC call on a function, called 'handle' that belongs to HandlerMs.
Ideally, I want ManagerMs to be able to import just the declarations of HandlerMs so that it can do something like (inside the ManagerMs class):
import HandlerMsApi from '<path-to-declaration-file?>'
...
class ManagerMs {
...
this.rpcClient.call(HandlerMsApi.handle.name) // instead of: this.rpcClient.call('HandlerMsApi.handle')
The point is that a certain service will have access to the declaration of another service and not the implementation.
Currently, both services can't import each other because of the way the project is structured.
So I thought of creating a shared library which will hold just the declaration files of the different modules, but that mean that .d.ts files aren't located next to their corresponding implementation files (.ts).
Questions are:
Is it a good idea?
How can I achieve such behaviour?
Currently, when I tried to do so I have the following .d.ts file (in a different folder than the implementation):
declare class HandlerMsApi {
handle(req: string): Promise<any>;
}
export = HandlerMsApi;
But when I try to compile (tsc) my code I get the following error:
"....handler.d.ts' is not a module"
Any help?
I'm creating a browser multiplayer card game with React and Socket.IO. On the client, I have a clientController class which is responsible for connecting to the server, and communicating with it using Socket.IO. This is also where I define listeners for game events (like "start_game" or "new_round"). All these events are handled by listeners in a gameService file (which exports a single instance of a GameService class per client).
I'm using TypeScript and styled-components, but I don't think it is relevant for this question.
I have a GameRoom component (mainly for rendering, not much logic), but my plan was to manipulate most or all game state inside my GameService instance. This obviously means that my GameService instance would need to have access to the React Context I set up (for accessing and changing state everywhere), which it can't have because it is not a React component.
I tried defining variables in my GameService class for later declaration inside gameContext file, like so:
//inside GameService class
class GameService {
setGame;
...
}
export default new GameService();
//inside gameContext file
import gameService from "./gameService"
...
const [game, setGame] = useState<Game>();
gameService.setGame = setGame;
Even doing it this way, which avoids calling useContext() inside a file which has nothing to do with React components, it doesn't work.
For example, inside my "start_game" event listener (inside my GameService instance), I call this.setGame(new Game()) and it gives me a "this.setGame is not a function" error.
I think this has more issues than just the state setters, as the "game" state itself would probably just be converted to a normal variable.
Is there a way to effectively use state inside a non React component? Or should I turn my GameService class into a component that just handles logic? If so, where should I place it in my component hierarchy?
I've read questions like Access EventEmitter Service inside of CustomHttp
where the user uses EventEmitter in his service, but he was suggested in this comment
not to use it and to use instead Observables directly in his services.
I also read this
question
where the solution suggests to pass the EventEmitter to the child and subscribe to it.
My question then is: Should I, or should I not subscribe manually to an EventEmitter? How should I use it?
TL;DR:
No, don't subscribe manually to them, don't use them in services. Use them as is shown in the documentation only to emit events in components. Don't defeat angular's abstraction.
Answer:
No, you should not subscribe manually to it.
EventEmitter is an angular2 abstraction and its only purpose is to emit events in components. Quoting a comment from Rob Wormald
[...] EventEmitter is really an Angular abstraction, and should be used pretty much only for emitting custom Events in components. Otherwise, just use Rx as if it was any other library.
This is stated really clear in EventEmitter's documentation.
Use by directives and components to emit custom Events.
What's wrong about using it?
Angular2 will never guarantee us that EventEmitter will continue being an Observable. So that means refactoring our code if it changes. The only API we must access is its emit() method. We should never subscribe manually to an EventEmitter.
All the stated above is more clear in this Ward Bell's comment (recommended to read the article, and the answer to that comment). Quoting for reference
Do NOT count on EventEmitter continuing to be an Observable!
Do NOT count on those Observable operators being there in the future!
These will be deprecated soon and probably removed before release.
Use EventEmitter only for event binding between a child and parent component. Do not subscribe to it. Do not call any of those methods. Only call eve.emit()
His comment is in line with Rob's comment long time ago.
So, how to use it properly?
Simply use it to emit events from your component. Take a look a the following example.
#Component({
selector : 'child',
template : `
<button (click)="sendNotification()">Notify my parent!</button>
`
})
class Child {
#Output() notifyParent: EventEmitter<any> = new EventEmitter();
sendNotification() {
this.notifyParent.emit('Some value to send to the parent');
}
}
#Component({
selector : 'parent',
template : `
<child (notifyParent)="getNotification($event)"></child>
`
})
class Parent {
getNotification(evt) {
// Do something with the notification (evt) sent by the child!
}
}
How not to use it?
class MyService {
#Output() myServiceEvent : EventEmitter<any> = new EventEmitter();
}
Stop right there... you're already wrong...
Hopefully these two simple examples will clarify EventEmitter's proper usage.
Yes, go ahead and use it.
EventEmitter is a public, documented type in the final Angular Core API. Whether or not it is based on Observable is irrelevant; if its documented emit and subscribe methods suit what you need, then go ahead and use it.
As also stated in the docs:
Uses Rx.Observable but provides an adapter to make it work as specified here: https://github.com/jhusain/observable-spec
Once a reference implementation of the spec is available, switch to it.
So they wanted an Observable like object that behaved in a certain way, they implemented it, and made it public. If it were merely an internal Angular abstraction that shouldn't be used, they wouldn't have made it public.
There are plenty of times when it's useful to have an emitter which sends events of a specific type. If that's your use case, go for it. If/when a reference implementation of the spec they link to is available, it should be a drop-in replacement, just as with any other polyfill.
Just be sure that the generator you pass to the subscribe() function follows the linked spec. The returned object is guaranteed to have an unsubscribe method which should be called to free any references to the generator (this is currently an RxJs Subscription object but that is indeed an implementation detail which should not be depended on).
export class MyServiceEvent {
message: string;
eventId: number;
}
export class MyService {
public onChange: EventEmitter<MyServiceEvent> = new EventEmitter<MyServiceEvent>();
public doSomething(message: string) {
// do something, then...
this.onChange.emit({message: message, eventId: 42});
}
}
export class MyConsumer {
private _serviceSubscription;
constructor(private service: MyService) {
this._serviceSubscription = this.service.onChange.subscribe({
next: (event: MyServiceEvent) => {
console.log(`Received message #${event.eventId}: ${event.message}`);
}
})
}
public consume() {
// do some stuff, then later...
this.cleanup();
}
private cleanup() {
this._serviceSubscription.unsubscribe();
}
}
All of the strongly-worded doom and gloom predictions seem to stem from a single Stack Overflow comment from a single developer on a pre-release version of Angular 2.
When you want to have cross component interaction, then you need to know what are #Input , #Output , EventEmitter and Subjects.
If the relation between components is parent- child or vice versa we use #input & #output with event emitter..
#output emits an event and you need to emit using event emitter.
If it's not parent child relationship.. then you have to use subjects or through a common service.
When you want component interaction, then you need to know what are #Input , #Output , EventEmitter and Subjects.
If the relation between components is parent- child or vice versa we use #input & #output with event emitter..
#output emits an event and you need to emit using event emitter.
If it's not parent child relationship.. then you have to use subjects or through a common service
There is no: nono and no: yesyes.
The truth is in the middle
And no reasons to be scared because of the next version of Angular.
From a logical point of view, if You have a Component and You want to inform other components that something happens, an event should be fired and this can be done in whatever way You (developer) think it should be done. I don't see the reason why to not use it and i don't see the reason why to use it at all costs. Also the EventEmitter name suggests to me an event happening. I usually use it for important events happening in the Component. I create the Service but create the Service file inside the Component Folder. So my Service file becomes a sort of Event Manager or an Event Interface, so I can figure out at glance to which event I can subscribe on the current component.
I know..Maybe I'm a bit an old fashioned developer.
But this is not a part of Event Driven development pattern, this is part of the software architecture decisions of Your particular project.
Some other guys may think that use Observables directly is cool. In that case go ahead with Observables directly.
You're not a serial killer doing this. Unless you're a psychopath developer, So far the Program works, do it.
From a pure implementation perspective, since emit and subscribe are part of the public interface of EventEmitter, they can be used for implementation.
For angular there was no compulsion to inherit from behaviour if it didn't want it to, Behaviour could have been a private member in EventEmitter class, something like,
public class EventEmitter{
private _behaviour=new Subject<void>();
private _behaviour$=this._behaviour.asObservable();
......
public emit(){
_behaviour.emit();
}
....
}
If it inherits from Behvaiour but doesn't behave like one, then it is violation of liskov's susbstitution principle.
This question already has answers here:
Invoke or BeginInvoke cannot be called on a control until the window handle has been created
(8 answers)
Closed 9 years ago.
I have a WinForm screen that is also a message consumer (using Rhino ESB). If I try to update anything on the screen when I receive a message, nothing happens. A call to Invoke gives me an error that the handle is not created. The form is definitely created though, I'm firing a message on button click on the form and the background process sends a message back. It's with this return message I want to update the UI.
THIS IS NOT A DUPLICATE QUESTION, NONE OF THE SUGGESTED SOLUTIONS WORK.
I believe the difference here may be because I'm using Rhino Service bus. Rhino may be constructing a separate instance of my form rather than the one I'm using. I think what I probably need to do is to have Rhino use my instance of the form as the consumer by passing my instance into the IoC container Rhino is using. Another alternative is to move the Consumer off to it's own class and inject my Form into the consumer, and put a public method on my Form for the Consumer to use. This may work fine with my app because this is the main form and will never be disposed unless the app is closed. This would become problematic on another form that may be instantiated multiple times. Perhaps I could have my form "observe" another static object that a separate Consumer class updates. Please give suggestions as to the best approach.
public partial class MainForm : Form, ConsumerOf<MoveJobCompletedEvent>
{
public void Consume(MoveJobCompletedEvent message)
{
// This does nothing!
txtLogs.Text = "\nJob completed!";
}
}
This throws an error:
this.BeginInvoke((MethodInvoker)delegate
{
txtLogs.Text += "\nJob job completed!";
});
ERROR: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
It seems that you're consuming a JobCompleted event before the window handle is created. You could try the following:
public partial class MainForm : Form, ConsumerOf<MoveJobCompletedEvent>
{
public void Consume(MoveJobCompletedEvent message)
{
if (!this.HandleCreated)
return;
this.BeginInvoke((MethodInvoker)delegate
{
txtLogs.Text += "\nJob job completed!";
});
}
}
Because I found the method named bindThread() is invoked multiple times at class named StandardContext in Tomcat 7 source code, especially in the method named startInternal(). I do not understand why need to call this method multiple times.
Actually the bindThread() is set the thread context classloader, but I don't konw why still use bindThread() and unbindThread() method pair in the startInternal() invoke multiple times.
Web application start and stop normally happens with the container class loader in effect. Some parts of the start (and stop) process (e.g. firing the application listeners) needs to take place with the web application class loader in effect. bindThread() and unbindThread() are the methods that switch to the web application class loader and back again respectively. The various elements of start and stop have to happen in a specific order so it is necessary to switch back and forth between class loaders.