Callback on transaction or commit() - ember-data

How can I achieve something similar like that?
App.saveManyDifferentModels()
App.store.commit(function() {
$("#spinner.gif").hide()
});

There is no generic hook at that moment on the transaction that would allow that.
However, if you are persisting a single record, you could add use the didCreate or didUpdate hook on the model.
Another option could be to handle that while changing state/route on the app.

Actually there is a way to do this. For example in your controller you can add a 'didUpdate' method to your model, like this:
var post = this.get("model");
post.didUpdate = function() {
$("#spinner.gif").hide();
};
this.get("store").commit();

Related

sub-property write commit withing store actions using vuex-pathify make.mutations

Here is how my store looks like:
const state = {
user: {
profile: {
phoneNumber: '',
}
}
}
const mutations = make.mutations(state)
const actions = {
submitPhoneNumber({commit}, phone_number) {
// blah blah
commit('SET_USER#profile.phoneNumber', phone_number);
}
}
But no such mutation can be found.
Maybe I could import store.js within store.js and use the set helper but I believe things can get pretty creepy specially because of the (In my opinion poor) design decision that the library creator has made to combine commit and dispatch (I believe being explicit would have been much better here)
Pathify author here.
You can't commit a mutation with sub-property syntax using Vuex mutations, because Vuex will treat it as a string.
You are correct that you would need to use store.set() to do this.
You can be explicit with commits and dispatches by appending a ! to the call. This is called "direct syntax":
https://davestewart.github.io/vuex-pathify/#/api/paths?id=direct-syntax
To commit directly using the sub-property syntax, use the Payload class:
https://github.com/davestewart/vuex-pathify/blob/master/src/classes/Payload.js
https://davestewart.github.io/vuex-pathify/#/api/properties?id=payload-class
Something like this should work:
import { Payload } from 'vuex-pathify'
commit('SET_USER', new Payload('SET_USER', #profile.phoneNumber', phone_number);
Looks like I haven't documented this, so I have a made a ticket here:
https://github.com/davestewart/vuex-pathify/issues/80
It's using a commit from a component, but should work just the same.
People have asked before if it would be possible to use Pathify-style commits in actions and I said it wasn't, but I've just thought of something that might make it possible.
Follow this feature request for more info:
https://github.com/davestewart/vuex-pathify/issues/79

Why should I use the action decorator in mobx

I'm trying to get my head around the usefulness of the action decorator in mobx, even after reading the doc, https://mobx.js.org/refguide/action.html
Still wondering why I should use #action or #action.bound, other than to enforce a pattern where a component cannot change the observable directly.
The above article mentions providing "useful debugging information". But where can I find this info? F12->Console doesn't show anything when calling an #action or #action.bound method.
Or am I doing something wrong in the below code?
Should I install some mobx debugger? Thanks.
class CommentStore {
#observable commentData = [];
#action.bound
updateComment(id, name) {
this.commentData.map(p => p.id === id ? p.name = name : p.name = p.name);
}
...
If you mutate more than an observable variables inside a method which is not decorated by #action, your derivations (autorun) will run multiple time. This issue is not present when you work with react. render function will run only once.
one of the things which #action decorator do is to prevent multiple invocation of your derivations.

Correct place to run script in vuex flow?

I have an action, setProducts, which I'm passing a payload which returned from a productSearch() method.
In my Vue component this looks as follows:
let products = productSearch();
this.$store.dispatch('setProducts', products);
However, I'm wondering if the correct way to do this would be to refactor my setProducts action to searchProducts then in my mutator call the productSearch() method.
So from my component I run:
this.$store.dispatch('searchProducts');
Then for my mutator method I'd have something like this:
searchProducts(state) {
state.products = productSearch();
},
Is there a more "correct" way to do this?
I think it would be better like this:
Component:
this.$store.dispatch('searchProducts')
Action:
searchProducts(state) {
commit('updateProducts', productSearch())'
}
Mutator:
updateProducts(state, products) {
state.products = products
}
Actions shouldn't directly affect state's values.
You always need to use commit and mutators to update your store variables, and your mutators should never call functions, they work like setters (receive a variable as paramater and apply it to the state variable).

Is it possible to `bind` a handlebars helper before render? (using express & hbs)

I've got a helper called feature that looks like this:
hbs.registerHelper('feature', function(request, flag, options) {
if (features(flag, request)) {
return options.fn(this);
} else if (options.inverse) {
return options.inverse(this);
}
});
And used in the template over and over like this:
{{feature request "some-feature"}} ... {{/feature}}
I'd love to be able to remove the request part in the template as it's always the same value and never changes. So I imagine I could bind request to feature when it's rendered, and obviously that changes each time and I don't want it spilling out to other request.
Something like:
res.render("page", {
feature: hbs.helper.feature.bind(null, req)
});
Is this possible?
If you are not using known helpers mode then the helper evaluation will check the context so you can pass in a bind like you have above and it should work.
Under the latest code in handlebars master the eval is something like:
helper = helpers.foo || (depth0 && depth0.foo) || helperMissing
helper.call(depth0, 1, {"name":"foo","hash":{},"data":data}
Where depth0 is the current context object. The caveat here is that helpers are given priority so you need to name them differently. You should also be able to do something like {{./foo bar}} to give priority to the local context's version but it appears that we have a bug where that isn't honored under this particular syntax construct.

Yii model is validating but data could not be saved

I have a yii application. Data is validated properly. the $model->validate() returns true but data is not being saved. Is there any way that I know about the error. It does nothing. neither prints error nor any warning.
if (isset($_POST['Invoice'])) {
$model->validate();
$model->attributes = $_POST['Invoice'];
if (!$model->validate()) {
die(CVarDumper::dump($model->errors,10,true));
}
if ($model->save()) {
die("Data saved");
$this->redirect(array('view', 'id' => $model->id));
} else {
CVarDumper::dump($model->attributes,10,true);
CVarDumper::dump($model->errors,10,true);
}
}
if you override beforeSave or afterFind method in your model,
public function beforeSave() {
return true; //don't forget this
}
public function afterFind() {
return true; //don't forget this
}
make sure you return true for those function
If save() is returning true and there are no errors as such in your database and queries. Only thing, thats possible is you haven't marked some of the column safe for mass assignment via "$model->attributes".
Make sure the column you are trying to save are marked safe in the "rules" function in your model. You can mark columns safe via adding the following rule in "rules" function in the model.
array ( "column_name1, column_name2 ....." , "safe" )
I've just ran into something similar to this. Everything was validating correctly, and $model->save() was returning true, but no data was saved in the database.
The problem and solution was that I was creating the $model object like so:
$model = ClassName::model();
but you need to create the object like so:
$model = new ClassName;
If you have this problem, you replace this:
$model->save(false)
This solves your problem.
If you use $model->save(); the filters is running that is not good for you.
Fire up some logging and see what going on...
I got the same error when I was using reCaptcha. I just did this and it worked:
$model->scenario = NULL;
Make sure you do this AFTER validation.
I had the same issue, my mistake was with the post name in the controller, where I used $model->save. I had given wrong - if(isset($_POST['postname']))
If I am not wrong, you are doing an AR save() in the $model->save() method. You do not get any error, but the data is not saved as well.
If this is the case you would like to do a:
die(CVarDumper::dump($arObj->errors,10,true));
after the $arObj->save(); call. Most of the time this happens because of the Database rejecting the values provided for insert or update.
Also do not override your model constructor:
function __construct() { } // don't do this
The issue for me was that I had a property for the column name in the ActiveRecord class, so it wasn't saving.
You should not declare properties for column names as I guess the magic methods __get() and __set() are used to save data, I guess by checking if there are column changes when you click the save() method to avoid useless SQL queries. In my case, because the column was a user-declared property, it wasn't in the columns list and therefore changes to it were not detected.
Hope this helps other people