Sencha Touch 2: store sync is not working as expected - sencha-touch

I am building an app related to order pickup. I have a list where order items are listed. The app has to send PUT request to Rest API in order to update the record when user tap on the list (specially on a button with in list item). My problem is if i tap a button within a list item, it sends multiple PUT requests but i think it should be only one request at a time.
My item tap function:
var store=Ext.data.StoreManager.lookup('storeOrderItem');
var index = store.findExact('orderitem_id', record.get('orderitem_id')),
orderItem = store.getAt(index);
//updating item store
orderItem.set('order_picker_id',NCAPP.app.loggedInUser.user_id);
if(NCAPP.app.currentWarehouse.is_main_store==0)
{
orderItem.set('pickup_status','picked#anotherlocation');
}
else
{
orderItem.set('pickup_status','picked');
}
store.setProxy({url:NCAPP.app.baseApiUrl+'/order/item/'+record.get('orderitem_id')});
orderItem.setDirty(true);
//updating with proxy (changes database)
store.sync();
When i monitor in google chrome debug screen, I see request has been sent for three times. (the store is loaded with three items). How can I avoid the three request and only one request per item tap? thanks

You have to confirm first that the itemtap() is called only once and then from there call a function in controller
Add the itemtap listener in the list as below.
listeners: {
itemtap: function(dataview, index, item, e) {
this.up('xtype').fireEvent('controllerfn');
}
}

Related

Refresh the Cart from the Backend

We have some custom functions for managing the Cart (add entries, remove cart etc.) which often times takes place in the backend.
I am searching for a way to refresh the cart in Spartacus so that it can show the actual data without the need of reloading the whole page. This is noticeable in the Minicart count as well as when we navigate to the cartpage. There you can see that the Data is not up to date. When you reload the page (F5) then the right data gets loaded.
Does someone have any idea how to force reload the "current" cart? I say current, cause when we remove the cart in the backend, we would expect that "hidden" method to create a new cart and give that back to Spartacus without reloading the page.
I found some sort of solution which feels kinda wonky and somehow does not work 100%:
refreshCart(): void {
this.getUser().pipe(
map((usr) => {
return usr;
}),
map(usr => {
this.cartService.reloadCart(usr, "");
}
)
).subscribe()
}
getUser(): Observable<string | undefined> {
return this.userIdService.getUserId().pipe(
map((userid) => {
return userid;
})
);
}
We extended the ActiveCartService and added a new method "reloadCart" which loos like the follwing:
reloadCart(userId: string, cartId: string): void {
this.loadOrMerge(cartId, userId, userId);
}
Please note that this is my first Angular Project and i feel that i miss some of the concepts (most noticeable i struggle with the whole Observables / subscribe / pipe / map and everything surrounding that).
Thank you in advance.
Not sure what spartacus version you are using, but I believe it applies to most of the versions.
To force a reload of the cart, you can use the MultiCartService to use the loadCart method.
Or if you don't want to use the actual service, you can always dispatch the action on your custom service, which what the loadCart method does from MultiCartService. You just need to provide the userId and cartId.
new CartActions.LoadCart({
userId,
cartId,
})

Passing full data from a store in to a view

I currently have a list that is populated via a store which works fine. When you click on a list item, my controller gets the record of that list item and passes those details to the view that is pushed on to the stack.
Is there a way to push the full data store in to the view that is added so that it can be referenced? (e.g. I have a list of events, and on the page for a specific event I want to reference the store and bring back the time of the next upcoming event after it)
Here is my current function that pushed the individual record to the view:
showDetail: function(dataview, index, item, record){
this.getMain().push({
xtype: 'ScheduleDetails',
data: record.data
});
}
Any help would be great. Thanks.
I found the answer. You can use dataview to access the store itself and then either pass that to the view as an object or just create a variable (as I have in the example below) and pass it as a parameter of your push function.
showDetail: function(dataview, index, item, record){
//Next event is the item in the record that I wanted to use to reference another record
var nextevent = dataview.listItems[record.data.nextevent]._record._data;
this.getMain().push({
xtype: 'ScheduleDetails',
data: record.data,
nextevent: nextevent
});
}

extjs 4.1 how to reset the itemselector

I am using extjs 4.1.1a for developing some application.
I had a form consisting of two combo-boxes and an item-selector.
Based on the value selected in first combo-box , the itemselector will load its data from database. This is working fine.
My problem is, if i reselect the first combo-box the new data will be displayed in itemselector along with previous data displayed in itemseletor .That is previous data displayed in itemselector will remain there itself.
for example: name "test1" consists of ids 801,2088,5000. on selecting test1 in firstcombobox itemselector must show output as below.
and if "test2" consists of ids 6090,5040. on selecting test2 in firstcombobox itemselector must show output as below.
problem is. for first time if i select "test1" from firstcombobox , output will come as expected. if i reselect "test2" from firstcombobox , output will come as below.
as you can see, previous data displayed (marked in red rectagle) remains there itself with new data displayed (marked with green rectangle).
I want for every reselection of first combobox, previously displayed data in itemselector to be erased before printing new data on itemselector.
How can I reset the itemselector for every reselection of first combobox?
You should remove all items from the store of the itemselector by the removeAll command. After that you should load the store of the itemselector.
itemselector.store.removeAll();
itemselector.store.load();
Any solutions above solve my problem.
i found solution from Sencha Forum.
https://www.sencha.com/forum/showthread.php?142276-closed-Ext-JS-4.0.2a-itemselector-not-reloading-the-store
in the itemselector.js file, change the line marked below.
populateFromStore: function(store) {
var fromStore = this.fromField.store;
// Flag set when the fromStore has been loaded
this.fromStorePopulated = true;
// THIS LINE BELOW MUST BE CHANGED!!!!!!!!!!!!
fromStore.loadData(store.getRange()); //fromStore.add(store.getRange());
// setValue waits for the from Store to be loaded
fromStore.fireEvent('load', fromStore);
},
You need to insert...
this.reset();
at the head of the function that is inserting the data.
As an example...
Ext.override( Ext.ux.ItemSelector, {
setValue: function(val) {
this.reset();
if (!val) return;
val = val instanceof Array ? val : val.split(this.delimiter);
var rec, i, id;
for (i = 0; i < val.length; i++) {
var vf = this.fromMultiselect.valueField;
id = val[i];
idx = this.toMultiselect.view.store.findBy(function(record){
return record.data[vf] == id;
});
if (idx != -1) continue;
idx = this.fromMultiselect.view.store.findBy(function(record){
return record.data[vf] == id;
});
rec = this.fromMultiselect.view.store.getAt(idx);
if (rec) {
this.toMultiselect.view.store.add(rec);
this.fromMultiselect.view.store.remove(rec);
}
}
}
});
are u got it?
when u select that combobox frist stoe of item selector is null after store load with ur pass the para meters
for example
store.load(null),
store.proxey.url='jso.php?id='+combobox.getrawvalue(),
store.load();
like that so when ur select a value in ur combobox that time ur used a listeners to ur combobox in that listners ur used above code , select ur some value in combobox that time frist store is get null after ur pass some values to json.php then store load with responce so that time old data is remove and new data load in that store
if u post ur code i will give correct code
I ran into the same issue with ExtJS 4.2.1. I got it to work by calling reload() on the data store and then setValue() with an empty string on the item selector in the data store's reload() callback.
Ext.create("Ext.form.field.ComboBox", {
// Other properties removed for brevity
listeners: {
change: function(field, newValue, oldValue, eOpts) {
Ext.getStore("ExampleStore").reload({
callback: function() {
Ext.getCmp("ExampleItemSelector").setValue("");
}
});
}
}
});
Ext.create("Ext.data.Store", {
storeId: "ExampleStore",
// Other properties removed for brevity
});
Ext.create("Ext.form.FormPanel", {
// Other properties removed for brevity
items:[{
xtype: "itemselector",
id: "ExampleItemSelector",
// Other properties removed for brevity
}]
});
For any folks that are curious, I'm fairly convinced there's a bug in the item selector's populateFromStore() function. When the function is called, it blindly adds all of the values from the bound store (store) to the internal store (fromStore). I suspect there should be a call to fromStore.removeAll() prior to the call to fromStore.add(). Here's the relevant code from ItemSelector.js.
populateFromStore: function(store) {
var fromStore = this.fromField.store;
// Flag set when the fromStore has been loaded
this.fromStorePopulated = true;
fromStore.add(store.getRange());
// setValue waits for the from Store to be loaded
fromStore.fireEvent('load', fromStore);
},
EDIT 12/18/2013
If you've configured any callback events on the item selector (e.g. change), you may want to disable the events temporarily when you call setValue(""). For example:
var selector = Ext.getCmp("ExampleItemSelector");
selector.suspendEvents();
selector.setValue("");
selector.resumeEvents();
I had the same problem and finally I decided to modify the extjs source code, not considering it a big issue as extjs itself its saying in the start of the file
Note that this control will most likely remain as an example, and not as a core Ext form
control. However, the API will be changing in a future release and so should not yet be
treated as a final, stable API at this time.
Based on that, as jstricker guessed (and sadly I didn't read and took me a while to arrive to the same conclusion), adding fromStore.removeAll() before fromStore.add() solves the problem.
Outside of the problem (but I think it can be interesting as well), additionally, I also added listConfig: me.listConfig in the MultiSelect configuration (inside createList), that way it's possible to format each item additional options (such as images, etc.) setting in the 'itemselector' the option listConfig as it's explained in the (irrealistic) documentation.
Need to reset the store used in ItemSelector that can be done by setting Empty object like below. Also need to call clearValue() method of ItemSelector component.
store.setData({});
ItemSelectorComponent.clearValue();

client web - how to get current record id at any time

I'm trying to work on the "different permissions based on workflow state" issue but I'm struggling with the fact that it seems impossible to get the id of the current object 'at any time' that is necessary in order to get the permission of that object. What I mean is that I manage to get it from the client state following jquery bbq docs like:
$.bbq.getState().id
BUT it looks like this is doable only AFTER a complete page load. I investigated this by placing some alert in the main view events, like:
openerp.web.PageView = openerp.web.PageView.extend({
on_loaded: function(data) {
this._super(data);
alert('page load ' + $.bbq.getState().id);
},
do_show: function() {
this._super();
alert('page show ' + $.bbq.getState().id);
},
reload: function() {
this._super();
alert('page reload ' + $.bbq.getState().id);
},
on_record_loaded: function(record) {
this._super(record);
alert('record loaded ' + $.bbq.getState().id);
}
});
and I found that when you open the page view (by clicking on an item in a search view, for instance) you get always "undefined".
Then, you get it into "reload" and "on_record_loaded" when passing from an object to another using paged navigation. And then, you miss it again when you click on the "edit" button.
In the form view I successfully got it only on the 1st load because it seems that some caching is in-place. So that, if I place a pdb into web client's fields_view_get and I do this into the form "init_view":
var ids = [];
if ($.bbq.getState().id){
ids = [parseInt($.bbq.getState().id)];
}
console.log(ids);
return this.rpc("/web/view/load", {
"model": this.model,
"view_id": this.view_id,
"view_type": "form",
toolbar: this.options.sidebar,
context: context,
ids: ids,
}, this.on_loaded);
I get it only the 1st time that the page gets loaded. The same happen if I take ids from
this.dataset.ids
I looked anywhere at the core web module and I can't find a proper API for this and it looks weird (above all on dataset) that we don't have a proper way for getting/working on the current record/s. Even the context and the session do not have any information about that.
Probably I should store this into the view itself on 1st load...
Thanks in advance for any pointers.
try:
this.view.datarecord.id
OpenERP 7 in form view:
debugged using google chrome
Try the combination of the
this.dataset.ids and this.dataset.index
like
curr_id = this.dataset.ids[this.dataset.index]
this might solve your problem.

Open graph stories of action I do show up on my ticker but not on my friends' ticker

I created a canvas app and defined action, object and aggregation. When I publish an action using javascript sdk by doing -
FB.api('/me/namespace:action?object=object_url', 'post',
function (response) {
if (!response || response.error) {
//failure
} else {
//success
}
});
I get success and it shows up on my ticker and timeline but my friend is not able to see anything related to this activity neither on his ticker nor in the news feed. The visibility of activity in this app is set to friends but still nothing shows up in firends' accounts.
It was because I had delete 4 aggregations created automatically and created a single aggregation that I thought would only be required. I deleted this action and aggregation, created a new one from scratch and updated aggregations with action/object and it worked.