Play framework event on Model delete - events

I am using Play framework 1.2.6. I am trying to get a Event or Listen some event if in my application any model call the delete or add. i.e. if deletion of data or addition happens in database through Model, then is there any way to get a event for this.
Please let me know if I am not very clear.
Thank you.

Try the #PreRemove annotation on your model method.
http://www.playframework.com/documentation/1.2.4/cheatsheet/model

You can override the _save() and _delete() methods in your model.
#Override
public void _delete() {
// .. do something
super._delete();
}
#Override
public void _save() {
// .. do something
super._save();
}

Related

LiveData Object keeps being null after getValue() is called

I want to update a member variable of an object inside my Repository on a LiveData- Object. The problem is, that if I call the getValue() Method, I keep getting an NullPointerException, although the value does exist inside my Room- Library.
My question now is, how do I get the value from the LiveData Object without calling the observe() Method? (I am not able to call the observe method inside my repository, cause that method wants me to enter a LifeCycleOwner- reference, which is not present inside my repository).
Is there any way to get the value out of the LiveData- object?
My architecture looks like that:
ViewModel --> Repository --> Dao
You need to initialize LiveData object in ViewModel before observing it in Activity/Fragment like this
ProductViewModel.java
public ProductViewModel(DataRepository repository, int productId) {
mObservableProduct = repository.loadProduct(mProductId);
}
public LiveData<ProductEntity> getObservableProduct() {
return mObservableProduct;
}
Here observableProduct is LiveData for observing product details which is initialized in constructor and fetched using getObservableProduct() method
Then you can observe the LiveData in Activity/Fragment like this
MainActivity.java
productViewModel.getObservableProduct().observe(this, new Observer<ProductEntity>() {
#Override
public void onChanged(#Nullable ProductEntity productEntity) {
mProduct = productEntity;
}
});
As you already setup your code architecture like
Flow of LiveData is
DAO -> Repository -> ViewModel -> Fragment
You don't need to observe LiveData in repository because you cannot update UI from there. Observe it from Activity instead and update UI from there.
As you are saying its giving null on getValue(), make sure you are updating db and fetching db from single instance of DAO as per I worked with DAO it will not notify db update of one DAO instance to 2nd DAO instance with LiveData
Also you can observeForever as suggested by #Martin Ohlin, but it will not be lifecycle aware and may lead to crashes. Check your requirement before observing forever
Refer to this for Full LiveData Flow
Refer to this for DAO issues
Edit 1 - Without using LifecycleOwner
You can use void observeForever (Observer<T> observer) (reference) method to observe LiveData without providing any LifecycleOwner as I provided by using this context in above example.
This is how you can observe LiveData without providing any LifecycleOwner and observe the LiveData in repository itself
private void observeForeverProducts() {
mDatabase.productDao().loadAllProducts().observeForever(new Observer<List<ProductEntity>>() {
#Override
public void onChanged(#Nullable List<ProductEntity> productEntities) {
Log.d(TAG, "onChanged: " + productEntities);
}
});
}
But you need to call removeObserver(Observer) explicitly to stop observing the LiveData which was automatically done in previous case with LifecycleOwner. So as per documentation
You should manually call removeObserver(Observer) to stop observing this LiveData. While LiveData has one of such observers, it will be considered as active.
As this doesn't require LifecycleOwner you can call this in Repository without using this parameter as you mentioned which is missing in your repository
In order for the LiveData object works well you need to use the observe method. That is if you want to use the getValue() method and expecting a non-null response you need to use the observe method. Make sure initialize the LiveData object in your ViewModel as #adityakamble49 said in his answer. For initialize the object, you can pass the reference of your LiveData object which was created in your Repository:
ViewModel.java
private LiveData<Client> clientLiveData;
private ClientRepository clientRepo;
public ViewModel(ClientRepository clientRepo) {
this.clientRepo = clientRepo;
clientLiveData = clientRepo.getData();
}
Then you have to observe your ViewModel from the Activity and call the method that you want to update in your ViewModel (or Repo, but remember that Repo conects with the ViewModel and ViewModel with the UI: https://developer.android.com/jetpack/docs/guide ):
Activity.java
viewModel.getClient().observe(this, new Observer<Client>() {
#Override
public void onChanged(#Nullable Client client) {
viewModel.methodWantedInViewModel(client);
}
});
I hope it helps.
I'm not sure exactly what you are trying to accomplish here, but it is possible to observe without a LifeCycleOwner if you use
observeForever instead of observe.
Livedata is used to observe the data streams. In case you want to call the get a list of your entities stored within the Live Data. Something like this can be helpful.
public class PoliciesTabActivity extends AppCompatActivity {
private PolicyManualViewModel mViewModel;
private List<PolicyManual> policyManualList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_leaves_tab_manager);
mViewModel = ViewModelProviders.of(PoliciesTabActivity.this).get(PolicyManualViewModel.class);
//Show loading screen untill live data onChanged is triggered
policyManualList = new ArrayList<>();
mViewModel.getAllPolicies().observe(this, new Observer<List<PolicyManual>>() {
#Override
public void onChanged(#Nullable List<PolicyManual> sections) {
//Here you got the live data as a List of Entities
policyManualList = sections;
if (policyManualList != null && policyManualList.size() > 0) {
Toast.makeText(PoliciesTabActivity.this, "Total Policy Entity Found : " + policyManualList.size(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(PoliciesTabActivity.this, "No Policy Found.", Toast.LENGTH_SHORT).show();
}
}
});
}
}
One more thing - for others with a similar problem - be aware that live data queries will execute only if there is a live observer (i.e. view listening for updates). It won't fill itself just by "laying" there in declarations, like this:
val myLiveData = repository.readSomeLiveData ()
So make sure that you are observing somewhere your LiveData object, either in view or through Transformations.

Preventing hide of the main dialog

I'm trying prevent the close of my application, but looking at JavaFX docs (and after some implementations) I noticed that setOnCloseRequest() is efficient only when the user try to close the window using close button or ALT+F4 shortcut. As I need intercept internal tries of close, I'm using setOnHiding(), this way I can catch all tries of close the main dialog of the application, however I still can't prevent the closing:
public abstract class AppBase extends Application {
public void init(){
dialogoPrincipal.getPainel().getScene().getWindow().setOnHiding(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent event) {
event.consume();
}
});
}
}
Is there something I'm doing wrong? Is there another approach to solve this problem?
CloseRequest events are fired by the GUI user and Hide events are called programmatically. So you can control the flow of code for hide event calls. Implement some wrapper util class like StageUtil.hideRequest(stage) or extend your own as stage.myHide() etc. The hiding event seems cannot be consumed and I think it is a right decision by design. The purpose of hiding and hidden events are described in their javadocs and there is no mention about consuming of them.
Try implementing a window event handler on your controller:
public class XYZ implements EventHandler<WindowEvent>
{
#Override
public void handle( WindowEvent closeEvent )
{
closeEvent.consume();
}
}
Or try implementing it on your AppBase class.

How to correctly override the SaveChanges function in EF 4.1

I need to automatically insert the current date when I create a new order in my EF 4.1 MVC3 web application. I also need to automatically add the currently logged in user - I'm using forms authentication.
After searching the web, I found that I need to override the SaveChanges() function and an article on StackOverflow showed how to do this: Entity Framework 4.1 Automatic date. However, I couldn't get the code to work.
Where does this code go?
How do I find out what is?
Sorry if the question is trivial - I'm new to EF.
B.
You can override in your context class,
public partial class YourDbContext: DbContext
{
public YourDbContext()
{
}
public override int SaveChanges()
{
// do your additional stuff here.. (Ex:- save current user)
return base.SaveChanges();
}
}
And the other option is you can set default values in the constructor of your entity,
Public class YourEntity{
public YourEntity(){
CreatedDate=DateTime.Now;
}
Public DateTime CreatedDate{get;set;}
}

Mvc3 custom event hooks

I have a Mvc3-Project where I want to register to custom event hooks.
So that I can register to an event like "User logon". I do not want to do it in the controller, because there is a business logic behind it in an other project.
So in my Mvc3-Project I want to write some classes that will have the code that has to be executed when a User is loged on. But how do I register these classes (or an instance of them) to the event. Is it a good idea to use reflection an search for all classes inherited from a special base class, or is there an other smarter way?
So again, I do not want to monitor the action that is called, I want that the business logic triggers some classes in my Mvc3-Project.
EDIT
As Chris points out in the comments below, MVC3 is stateless, meaning that with this solution you would have to resubscribe for these events on every request. This is probably not a very good solution for MVC.
Have you considered an global event service?
Rough example:
class Example : IEventReceiver
{
public void Init()
{
EventService.Subscribe("Logon", this);
}
private void OnEvent(string eventName)
{
// Do logon stuff here.
}
}
You would need to create the EventService class, which might be a singleton or service. It might have interface similar to the following:
public interface IEventService
{
void Subscribe(string eventName, IEventReceiver receiver);
void Unsubscribe(string eventName, IEventReceiver receiver);
void DispatchEvent(string eventName);
}
public interface IEventReceiver
{
void OnEvent(string eventName);
}

Is it possible to seamlessly display an ajax spinner for every GWT RPC call?

I have a GWT application that uses RPC calls heavily. I would like to display a spinner icon whenever a call is in progress. It is easy enough to display the icon, but I want to do it seamlessly in one place so I don't have to explicitly hide and show the icon for each call.
I guess I am looking for something similar to jQuery's ajaxStart and ajaxStop events.
Has anyone done something like this before?
Cheers
Tin
Why don't you implement this behaviour in a concrete implementation of AsyncCallback and subclass all the AsyncCallbacks from this one. Alternatively you could use a decorator pattern where you use a regular AsyncCallback and decorate it with another one that shows/hides the popup.
Alternatively, if you use a Command Pattern, you could just add these events to your command pattern implementation and you can register a handler that shows/hides a popup every time a request is send/received.
In response to comments that suggest a Decorator is not enough.
abstract class AbstractAsyncCallback <T> implements AsyncCallaback <T>
{
public AbstractAsyncCallback ()
{
Foo.showIcon();
}
#Override public void success (T t)
{
doSuccess(t);
Foo.hideIcon();
}
#Override public void failure ()
{
doFailure();
Foo.hideIcon();
}
public abstract void doSuccess (T t);
public abstract void doFailure (T t);
};

Resources