Pimcore Which event is fired when first time product save? - events

Pimcore How to get event for first time product save using backend.
I have to apply some logic for first time product creation in pimcore.
How to find event name.

The name of the event is 'object.preAdd'.
If the Id of the saved object is 0, it's a newly created one
\Pimcore::getEventManager()->attach("object.preAdd", function (\Zend_EventManager_Event $e) {
// your code goes here
});
It would probably be best if you stick the code above into a custom made plugin to ensure it's executed on every call.
See https://www.pimcore.org/docs/latest/Extending_Pimcore/Event_API_and_Event_Manager.html for more information

Related

Cache emitted value for dependent observable but not source observable

I am currently implementing a new feature at work. The app wants to give sellers an admin where they can see various things. An example of one of the things they can see on their dashboard is their last 10 orders.
The order's API only returns an array of various ids (customer id, product id, seller id, etc) In order to populate the orders page, I have to make 3 different API call on each order to get the data to render on the order list page
Now that I have to create a dashboard that is different from the order list page, I do not want to make such a tedious API call again. I want to create a dashboard$ observable that has the last emitted value of orderList$ but I do not want anything subscribed to orderList$ to be cached.
So when orderList$ is called, it gets the lastest orderList data from the server (I do not feel something as sensitive as order list should be cached), when dashboard$ is called, get the last emitted value of orderList$ and if orderList$ has not emitted any values then dashboard$ can make a request to retrieve order list.
When working with a reactive state of mind, I like to define what should happen based on events. By this I mean that I'll have a Subject in which in can push values into to notify an event and from there we can react to these events.
In your case, here's an idea for what you want:
const navigationToOrdersPage$$ = new Subject<void>();
const refreshOrdersButtonClicked$$ = new Subject<void>();
const orders$: Order[] = merge(
navigationToOrdersPage$$,
refreshOrdersButtonClicked$$
).pipe(
switchMap(() => yourOrderService.getOrders()),
shareReplay({
bufferSize: 1,
// make sure that even if we don't have anyone subscribed to that observable
// we keep the result in the cache and if we ever go to the orders page or click
// on the refresh button it'll be updated anyway but with this it's safe to navigate
// to another page than orders and the dashboard and if you go back to the dashboard
// you'd still get an instant result
refCount: false,
})
);
So here it'd be safe to reuse this observable on both the admin and the dashboard page. Of course, you'll need to call next on the 2 subjects when appropriate so that the orders can be refreshed when they need to.

Google Publisher Tag, how to remove event listener from Service

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.

Multiple NetSuite Script Event Types

I'm new to NetSuite and have been tasked with integrating another system with NetSuite. I've created a User Event script that needs to run against multiple NetSuite events. The deployment interface seems to only let me assign the script to Create OR Edit, but not both. Is this not possible or what am I doing wrong?
Thanks,
You can define the events on which the UE script runs within the script, and leave the event type assignment in the deployment record blank.
Firstly, if you leave the event type blank in the UI and don't include logic withing the script to limit when it runs, it will be triggered on all event types (create, edit etc) whenever the triggering event occurs (beforeLoad, beforeSubmit, afterSubmit).
Selecting the event type in the UI is an easy shortcut to limiting when a script runs without having to worry about additional script logic; however, for maximum flexibility you can use script logic as follows or modify to suit your needs (in SS2.0):
function beforeSubmit(scriptContext) {
log.debug('type', scriptContext.type);
if (scriptContext.type !== scriptContext.UserEventType.CREATE) {
log.error('Exiting script', 'Context type is ' + scriptContext.type);
return;
}
//Do your work here
}

Difference between dispatch and emit in Flux/React Native

I'm new in Flux/React Native.
I'm quite confused about dispatch vs emit using in Flux.
What is the main difference between them? And what happen when I use same Action Type in dispatch and emit.
For example:
Dispatcher.dispatch({
actionType: 'ACTION1'
});
SomeStore.emit('ACTION1');
In Flux, events are emitted by the store indicating a change in its state. This 'change' event is listened to by views. This will prompt a view to fetch new state from the store. Mind you, the event never contains payload / information about the new state. It is really just what it reads - an event.
Actions are slightly different. While they are indeed events, they are things that occur in our domain eg., Add item to cart. And they carry a payload that contains information about the action, eg.,
{
id: ‘add-item-to-cart’,
payload: {
cartId: 123,
itemId: 1234,
name: ‘Box of chocolates’,
quantity: 1
}
}
Actions are 'dispatched' from the views and the store(s) responds to the dispatch by possibly changing its state and emitting a 'change' event.
So basically:
A view dispatches an action with a payload (usually due to a user interaction) via the dispatcher
The store (which had previously registered itself with the dispatcher)
is notified of the action and uses the payload to change its state and emit an event.
The view (which had previously registered itself with the store) is notified of the change event which causes it to get the new state from the store and change itself.
So that's the difference. And about the question "use same Action Type in dispatch and emit", it doesn't really make sense, does it?
I suggest you read this blog post - http://blog.andrewray.me/flux-for-stupid-people/ (The title means no offence BTW :))
You already know this, but I'll say it again: A unidirectional data flow is central to the Flux pattern. That means data (not control) always flows in one direction.

Flux Store and actions with temporary data

Note: This is a follow-up question of https://stackoverflow.com/questions/32536037/flux-store-collection-by-criteria-vs-single-item but it is independent to understand and answer.
Imagine we have an application for managing (CRUD) Tasks. One operation is a Task editing.
First the edit view loads the Task using an action creator that asynchronously fetches it from the server and dispatches TASK_LOAD_SUCCESS event together with the Task payload. Next a Task Store stores the Task and emits a change event so that the edit view can read it and fill the form.
When the user submits the form the changes should be saved and the edit view should be closed.
On the submit the edit view tells action creator to asynchronously save the Task. On AJAX success the TASK_SAVE_SUCCESS is dispatched (to the Task store).
Q1: What should the Task Store do? Should it update its internal flag that a task has been saved then emit the change event and then the view should read that flag from the store and close itself if it is true?
Q2: Should the Store find the Task in the collection of the previously loaded Tasks and update it there? Other Tasks in the collection will remain stale (see Q2 in https://stackoverflow.com/questions/32536037/flux-store-collection-by-criteria-vs-single-item).
Q3: What if we edit the Task again? The Store still has the flag that the Task has been successfully saved and it closes itself immediately. But it was from the previous save. How to deal with it?
Simmilar problem arises if we want to delete a Task. We use an optimistic locking and therefore we must first read the Task from the server then show the confirmation dialog and finally delete the Task on the server (providing ETag from the first read).
Q4: How to use the store to signal that the Task has been loaded for the deletion? During this AJAX call there might another asynchronous read operation become complete and it would clash with this one. Should there be a separate Store for a Task deletion?
Q5: This is same as Q1. After the deletion how to tell the view that it is done so it can close the confirmation dialog?
Q1-Q3: you may store an edit_timestamp in TaskStore and open_timestamp for confirmation dialog. On emitChange you may compare if edit_timestamp > open_timestamp.
Q4: you may cache request Promise for each taskId on fetch request. So instead doing the same request twice (read/delete fetch for the same taskId), you may subscribe on the existed Promise. That allow you to keep only the single instance of task, and I hope avoid Q5 problems:
//To imagine how to arrange promise-based async interaction you may look here http://mjw56.github.io/handling-asynchronous-data-flow-in-flux/index.html
var promises = {};
//Returns Promise
var asyncGetCall = function(taskId) {...}
var getTaskForDelete, getTaskForRead;
getTaskForDelete = getTaskForRead = function(taskId) {
if (!promises[taskId]) {
promises[taskId] = asyncGetCall(taskId);
}
return promises[taskId];
}
getTaskForDelete(10).then(function() {...}); //do asyncGetCall
getTaskForRead(10).then(function() {...}); // do nothing, wait for the first req results

Resources