Google Publisher Tag, how to remove event listener from Service - google-publisher-tag

There seem to be several questions on how to register events to a gpt service:
Google Publisher Tag registering to Events
registering to events with google publisher tag
How to do this is clearly defined in the documentation:
googletag.pubads().addEventListener('eventName', callbackFn);
I add my event to the service when the component (React) mounts inside the callback function of window.googletag.cmd.push as described in this tutorial by Google.
Now the problem is that every time I change page, more event listeners are added to the service. I can make sure only one event listener executes on the actually existing slots by using this method (from the documentation):
googletag.pubads().addEventListener('impressionViewable', function(event) {
if (event.slot == targetSlot) { // will only run on target slot
// Slot specific logic.
}
});
But more an more event listeners will remain active and keep on executing (without executing the code within the if-statement).
Now, I assumed google would have implemented something like this (to run on componentWillUnmount):
googletag.pubads().removeEventListener('eventName', callbackFn);
But it doesn't exist in the documentation and I can't seem to find any way to remove active event listeners from the service?

So I went with this:
let eventListnerCreated = false;
if(!eventListnerCreated) {
eventListnerCreated = googletag.pubads().addEventListener("slotRenderEnded", function(event) {
// blablabla
});
}
Not clean. But will work.
I know this doesn't solve the original issue of removing the event listener, but this will let's not create event listeners again and again.

Related

Which event triggered at start of Fiori app?

I'm trying to create a FLP plugin which executes and does some checks before and a will be opened from the launchpad. If those checks fail the app shouldn't start up and instead it should display a dialog which informs the user that the application isn't available right now.
So the creation and configuration of the FLP plugin was successful. But now I'm stuck because I don't know which event I need to listen to. While searching through the internet I found these to approaches:
return Component.extend("ch.srgssr.zcaflpmntchk.Component", {
...
init: function () {
...
sap.ui.getCore().getEventBus().subscribe(
"sap.ushell",
"appOpened",
(e1, e2, appMeta, e4) => console.log("onAppOpened", {e1, e2, appMeta, e4}),
this
);
return Component.extend("ch.srgssr.zcaflpmntchk.Component", {
...
init: function () {
...
sap.ushell.Container.getService("AppLifeCycle").attachAppLoaded(() => console.log("attachAppLoaded"));
Unfortunately both events are fired after the app is loaded and no matter what I do (or throw) I can't stop loading the app once the event is fired.
So on which event do I need to listen to be able the stop loading the app? Is there a "beforeAppLoaded" or something? Can't find a proper list of available events. I'm looking through several code examples and taking possible solutions from there.

How to call a function before and then depending on data update state-React-redux

I've a drop down on select the saga is called and the same component must be used. The sagas are called the only thing not happening is the set state is updating before the saga call therefore the component never updates the data.
recievedChangeValue=(selectVal)=>{
console.log(selectVal)
if(selectVal==='Yearly'){
this.props.getYearlySales() **//call to saga**
this.setState({salesData:this.props.yearlySales}) **//it updates before the called saga ends**
}
if(selectVal==='Decade'){
this.props.getSales()**//call to saga**
this.setState({salesData:this.props.dataSales}) **//it updates before the called saga ends**
}
}
I know the callback but here the state must be updated only after the saga call.I'm working onto it since past day I've no idea as to what has to be done. Any help is appreciated.Please lemme know as to where i'm going wrong.
You can't wait in component for the saga to finish, because this.props.getSales isn't really calling a saga - it is just dispatching an action.
When an action is dispatched something can happen in your app based on that, but the way the pattern works is that the "dispatcher" doesn't know about any of that.
The only common way saga can communicate with components is through changing redux state. So instead of changing local state in the callback you will have to wait for the dateSales prop to change and then update the local state using getDerivedStateFromProps.
static getDerivedStateFromProps(props) {
return {salesData: props.dataSales}
}
For more info on using getDerivedStateFromProps see
https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops
https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data-when-props-change
https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state
https://reactjs.org/docs/hooks-faq.html#how-do-i-implement-getderivedstatefromprops
recievedChangeValue=(selectVal)=>{
this.setState({selectedSalesData:selectVal},
()=>{
if(selectVal==='Yearly'){
this.props.getYearlySales()
}
if(selectVal==='Decade'){
this.props.getSales()
}
}
)
}
The following I wrote in render
let SalesData=this.handleSalesData(selectedSalesData)//calls on selecteddata and it works like a charm

Testing assertDispatched only works when using event helper

Registering service provider:
public function register()
{
$this->app->singleton(CartInterface::class, function ($app) {
return new SessionCart($app['session'], $app['events']);
});
}
Firing events within the service above:
$this->events->fire('cart.added', $item);
Testing the service:
public function it_can_add_an_item()
{
Event::fake();
$this->cartService->add(new Item);
$this->assertEquals(1, $this->cartService->count());
Event::assertDispatched('cart.added');
}
Result:
The expected [cart.added] event was not dispatched.
If instead of using $this->events to fire events I just use the event helper like event('cart.added') I'm back to green.
I'm not dying for using the object oriented approach, but I'm really curious about the reason it doesn't work here, because the event helper seems to be using an instance of the dispatcher right from the container just like I do when registering the service.
Any clue?
This is what happens when your test is executed:
The laravel application is bootstrapped; it binds the non-fake event dispatcher to the service container
You bind the CartInterface to the service containing and pass the currently binded event dispatcher (the non-fake one) as a parameter
After the application has been bootstrapped, you swap the event dispatcher with the fake one, however, your CartInterface has already been resolved (since its a singleton) and does not know that the event dispatcher has been swapped
Therefore, the CartInterface still uses the non-fake event dispatcher and your tests fail if you try to make any event assertions. However, if you use the Event facade inside your CartInterface, the event dispatcher will be resolved when you are actually using it, and this is after the dispatcher has been swapped with the fake one. So in this case, you actually get the event fake you want and your tests pass.

Azure, SubscriptionClient.OnMessage, and Sessions

Does the Azure Service Bus Subscription client support the ability to use OnMessage Action when the subscription requires a session?
I have a subscription, called "TestSubscription". It requires a sessionId and contains multipart data that is tied together by a SessionId.
if (!namespaceManager.SubscriptionExists("TestTopic", "Export"))
{
var testRule = new RuleDescription
{
Filter = new SqlFilter(#"(Action='Export')"),
Name = "Export"
};
var subDesc = new SubscriptionDescription("DataCollectionTopic", "Export")
{
RequiresSession = true
};
namespaceManager.CreateSubscription(sub`enter code here`Desc, testRule);
}
In a seperate project, I have a Service Bus Monitor and WorkerRole, and in the Worker Role, I have a SubscriptionClient, called "testSubscriptionClient":
testSubscriptionClient = SubscriptionClient.CreateFromConnectionString(connectionString, _topicName, CloudConfigurationManager.GetSetting("testSubscription"), ReceiveMode.PeekLock);
I would then like to have OnMessage triggered when new items are placed in the service bus queue:
testSubscriptionClient.OnMessage(PersistData);
However I get the following message when I run the code:
InvalidOperationException: It is not possible for an entity that requires sessions to create a non-sessionful message receiver
I am using Azure SDK v2.8.
Is what I am looking to do possible? Are there specific settings that I need to make in my service bus monitor, subscription client, or elsewhere that would let me retrieve messages from the subscription in this manner. As a side note, this approach works perfectly in other cases that I have in which I am not using sessioned data.
Can you try this code:
var messageSession=testSubscriptionClient.AcceptMessageSession();
messageSession.OnMessage(PersistData);
beside of this:
testSubscriptionClient.OnMessage(PersistData);
Edit:
Also, you can register your handler to handle sessions (RegisterSessionHandler). It will fire your handle every new action.
I think this is more suitable for your problem.
He shows both way, in this article. It's for queue, but I think you can apply this to topic also.

How to disable BackgroundTransferRequest's TransferStatusChanged event handler after I unsubscribed it?

I'm using background transfer to download videos and I subscribed each request's TransferStatusChanged and TransferProgressChanged event to monitor it's status and download progress. When I cancelled one background transfer request using BackgroundTransferService.Remove() method, it fired TransferStatusChanged event as msdn mentioned. I don't want to execute event handlers, so I try to unsubscribe event before removed the request, like code below:
BackgroundTransferRequest transferToRemove = BackgroundTransferService.Find(requestId);
if (transferToRemove != null)
{
transferToRemove.TransferStatusChanged -= transfer_TransferStatusChanged;
transferToRemove.TransferProgressChanged -= transfer_TransferProgressChanged;
BackgroundTransferService.Remove(transferToRemove);
}
but TransferStatusChanged event handler still fired. Can anyone help me?
BackgroundTransferService.Remove(transferToRemove); only Accepts the request. It will take sometime to remove it. Meanwhile, you again call the Add() function and thus you got one more event i.e. transfer_TransferProgressChanged.
In event transfer_TransferProgressChanged, first check BackgroundTransferService contains your request or not.
if(BackgroundTransferService.Requests.Contains(m_currentRequest))
{
BackgroundTransferService.Remove(m_currentRequest);
UnsubscribeYourEvents();
DoOtherStuffRealtedToDownload();
}

Resources