SignalR callback in javascript - signalr

Is there a way to pass a callback function for SignalR? Right now I have on my site.js
messageHub.client.sendProgress = function (progress) {
//doSomething with progress
}
What I would like to have is
messageHub.client.sendProgress = function (progress,callback) {
callback(progress);
}
This would enable me to define different callback functions from web pages for the same signalR method.
Right now I am doing it in kind of a hack-ish way by defining a function on my web page
function fnSendProgress(progress) //define this for site.js.
{
//do something here
}
and then in site.js calling it by
messageHub.client.sendProgress = function (progress) {
debugger;
//have a definition of a function called fnSendProgress(progress)
//if found it will call it else call default
if (typeof fnSendProgress == 'function') {
fnSendProgress(progress);
}
else {
//do something at site.js level
}
};
It works, but I was wondering if there is a cleaner method.
Any help much appreciated.

Use closures:
function createfunction(callback)
{
return function(progress) { callback(progress); }
}
messageHub.client.sendProgress = createFunction(callback)
First you define a function "createFunction", which given a callback returns another function with one argument, which calls the specified callback.
Then you assign the result of calling that function to signalr's sendProgress.
In other words: for each callback you want you dynamically generate a function with one argument, which calls the callback and passes the argument to it.

Related

Run sequential jobs/functions in Kotlin Coroutines with livedata

fun viewDidLoad() {
observeViewModel()
initializeUI()
getVideos()
getQuestions()
}
fun initializeUI() {
/*
1 - Create a list as;
VideosTitleRow("Videos"),
VideosBodyRow(null),
QuestionTitleRow("Questions"),
QuestionsBodyRow(null),
...."
Note: The bodies are null right now. There will fill with correct values after.
---
2 - Call updateUI functions for update ui with initialize list.
*/
}
fun getVideos() {
viewModel.getVideos()
}
fun getQuestions() {
viewModel.getQuestions()
}
fun observeViewModel() {
// Videos
CoroutineScope(Dispatchers.IO).launch {
when (flow) {
// ...
is VideosFlow.DataReceived -> {
val row = SectionVideosBodyData(flow.videos)
updateUI(1, row)
}
}
}
// Questions
CoroutineScope(Dispatchers.IO).launch {
when (flow) {
// ...
is QuestionsFlow.DataReceived -> {
val row = SectionQuestionsBodyData(flow.questions)
updateUI(3, row)
}
}
}
// And others LiveDatas under observing ....
}
fun updateUI(indexAt: Int? = null, row: BaseAdapterData = null) {
/*
If indexAt and row parameters are not null;
edit the global row list then created new row list from this (global list) and send the new list to adapter for update ui.
If parameters are null; send the global list to adapter for update ui.
*/
}
This is the current structure.
Let me try to explain what is problem;
When i start the initializeUI() function i know when it will finish the job. Because this is a synchronous function.
getVideos() or getQuestions() functions are a synchronous functions too but they start to api call, send request, take response, convert to ui model, bla bla operations. And we have to observe the results. So, we don't know when this job will finish!
getVideos() function just like says to viewModel.getVideos; "Let me know when you see the red car" but we can't know when is the red car pass on street.
In this case; although getQuestions() function is called before getVideos(), it may finish before it. In fact, both can end at the same time.
Here is i need;
I want to use kotlin coroutines scopes in getVideos(), getQuestions(), ... functions run as asynchronous but every job must wait for finished updateUI() function.
1- initializeUI() function runs, create a list, send to adapter, update the ui,
2- getVideos() or getQuestions() runs as asynchronous,
let say; livedata(getVideos) finish the their work but livedata (getQuestions) still working.
getQuestion() when call the updateUI() function, getVideos() can not call until updateUI() function finished called from getQuestion()
I know this is a complicated case :)
But the LiveData is messing up my mind.
I tried Mutex but although getVideos() or getQuestions() functions are synchronous, they starts an asynchronous job.
(Kotlin Coroutines sequential execution)

How to Dispatch symfony events within entity manager transaction

I am looking for a smarter way to dispatch a symfony event within entity manager transactional, so that in case of rollback it won't complain.
Here's the sample of code:
$this->em->transactional(
function () use ($xyz, $oldXyz) {
if ($oldXyz !== null) {
$this->doRemove($oldXyz);
}
$this->em->persist($xyz);
}
);
Where:
private function doRemove(XyzInterface $oldXyz): void
{
$this->em->remove($oldXyz);
$this->em->flush();
$this->dispatcher->dispatch(new XyzEvent($oldXyz), XyzEvents::onXyzDeleted);
}
This thing will complain 'app.ERROR: Pending transaction on master connection' because this due to event dispatching cannot be rollback.
I can not move out event dispatch from doRemove, because it's used somewhere else plus it's job of doRemove to dispatch this event here, since actual removing happens here only.
Any help would be appreciated, thank you all in advance.
Just return $oldXyz to the caller (by editing the closure as follows)
function () use ($xyz, $oldXyz) {
if ($oldXyz !== null) {
$this->doRemove($oldXyz);
return $oldXyz;
}
$this->em->persist($xyz);
return null;
}
Then check for returned value and dispatch
$oldXyz = $this->em->transactional(...);
if ($oldXyz instanceof <FQCNForOldXyz>) {
$this->dispatcher->dispatch(new XyzEvent($oldXyz), XyzEvents::onXyzDeleted);
}
Didn't tried directly, but I'm pretty confident it works.

Calling different callbacks for stub on firstcall and second call

I'm looking for a way in sinon to call different functions in first and second call to the stub method.
Here is an example:
var func1 = function(connectionPolicy, requestOptions, callback) {
callback({code: 403});
}
var func2 = function(connectionPolicy, requestOptions, callback) {
callback(undefined);
}
var stub = sinon.stub();
// Something of this form
stub.onCall(0) = func1;
stub.onCall(1) = func2;
request.createRequestObjectStub = stub;
So that when request.createrequestObjectStub gets called internally(when calling a public API), I see this behavior.
Sinon version: 1.17.4
Environment: Node JS
The only way I found to do what you want (with onCall(index) and an anonymous stub) is with bind JS Function.
This would be:
stub.onCall(0).returns(func1.bind()());
stub.onCall(1).returns(func2.bind()());
If you use stub.onCall(0).returns(func1()); the function func1 is executed when defining that onCall, that is why you need the .bind.
Anyway, you have other options, like returning a value directly with .onCall(index).returns(anObject); or defining a counter that is incremented each time your stubbed method is called (this way you know in which n-call you are and you can return different values).
For these three approaches, you can see the following fiddle with examples: https://jsfiddle.net/elbecita/jhvvv1h1/
onCall worked for me.
my code looks like:
const stubFnc = sinon.stub(myObject, "myFunction");
stubFnc.onCall(0).returns(mockObject1);
stubFnc.onCall(1).returns(mockObject2);
This is an old thread, but atleast as of Sinon 1.8, a more efficient way to solve this would be chaining sinon.onCall(arg) with callsFake().
So, in your use-case, you could do the following:
var func1 = function(connectionPolicy, requestOptions, callback) {
callback({code: 403});
}
var func2 = function(connectionPolicy, requestOptions, callback) {
callback(undefined);
}
var stub = sinon.stub();
// Solution
stub.onCall(0).callsFake(func1);
stub.onCall(1).callsFake(func2);
request.createRequestObjectStub = stub;
You can use callsArg and callsArgWith from sinon.stub() to make sinon call the callbacks
Causes the stub to call the argument at the provided index as a callback function. stub.callsArg(0); causes the stub to call the first argument as a callback. source
Then you can do something like:
myStub.onCall(0).callsArgWith(0, first);
myStub.onCall(1).callsArgWith(0, second);

Callback after __doPostBack()?

I am refreshing an UpdatePanel with Javscript by calling a method like so:
reloadDropDown = function (newValue)
{
__doPostBack("DropDown1", "");
selectNewValueInDropDown(newValue);
}
Inside my UpdatePanel is a <select> box that I need to select an <option> with a newValue. My problem is that my selectNewValueInDropDown method is being called prior to the __doPostBack from completing. Is there a way I can "wait" for the postback before calling my selectNewValueInDropDown method?
To make my comment more concrete, here's the idea:
reloadDropDown = function (newValue)
{
var requestManager = Sys.WebForms.PageRequestManager.getInstance();
function EndRequestHandler(sender, args) {
// Here's where you get to run your code!
selectNewValueInDropDown(newValue);
requestManager.remove_endRequest(EndRequestHandler);
}
requestManager.add_endRequest(EndRequestHandler);
__doPostBack("DropDown1", "");
}
Of course, you probably want to handle race conditions where two requests overlap. To handle that, you would need to keep track of which handler is for which request. You could use something like ScriptManager.RegisterDataItem on the server side, or call args.get_panelsUpdated() and check to see if the panel you're interested it was updated.
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
function BeginRequestHandler(sender, args)
{
//
}
function EndRequestHandler(sender, args)
{
//request is done
}

Call function after remote call in Flex

I have a function in Flex which has three function in it.
public function update():void
{
A(); \\Dispatches a event with Remote Call
B(); \\Dispatches another event with Remote Call
C();
}
I wan't to call C() after both A() and B() have returned from their call and set particular variables. How can i do that?
If you find yourself doing this often (esp. with more than 2 remote calls), you might want to write your own custom class that handles AsyncTokens from remote calls with a final result() function that is invoked when all remote calls end in success.
If not, since ActionScript is single-threaded, you can just use a local variable to track whether both calls have succeeded.
private var resultFromRemoteCallA:Object;
private var resultFromRemoteCallB:Object;
private function handleRemoteCallA(event:ResultEvent):void {
resultFromRemoteCallA = event.result;
C();
}
private function handleRemoteCallB(event:ResultEvent):void {
resultFromRemoteCallB = event.result;
C();
}
private function C():void {
if (resultFromRemoteCallA && resultFromRemoteCallB) {
// do some thing with the results.
}
}
private function update():void {
resultFromRemoteCallA = resultFromRemoteCallB = null;
A(); B();
}
If you expect null values, you might want to use a boolean variable to track the invocation of the result handler instead.
EDIT: since the author indicated that the dispatch happens in another class, another way to do it would be to pass along a responder and attach it to the AsyncToken like so (in the callee):
private function dispatchRemoteCall(resultHandler:Function, faultHandler: Function): void {
var resultToken: AsyncToken = remoteObject.foo('bar'); // remoteObject may or may not have a result/fault handler
resultToken.addResponder(new mx.rpc.Responder(resultHandler, faultHandler));
}
Then, you can pass along listeners to be invoked when the remote call finishes (at which point you can choose to let the dispatching class store the result or handle it in the caller), like so:
private function update(): void {
classA.dispatchRemoteCall(handleRemoteCallA, handleRemoteCallAFault);
}
If you find yourself doing this a lot, you may also want to look into having a framework do global event routing, like Parsley or Spring Actionscript.

Resources