Refresh data in table after creating a record - javascript

In my Ui5 app I have added CREATE operation using oData. But when i am trying to create entry it is getting added in backend but in table it is showing NO DATA (refer image 1). but when I refresh the same page it is there (refer image 2). With single entry ,it is automatically getting refreshed 
problem is with Multiple entries.
Please refer the screenshot and code for clear view.
After Clicking CREATE button:
After Refreshing WebPage:
onCreate: function() {
var oModel = this.getView().getModel();
var contactEntry1 = {
ProductID: 'KT-1960',
TypeCode: 'AD',
SupplierID: '0100000001',
TaxTarifCode: 1,
Category: 'Notebooks',
MeasureUnit: 'EA',
CurrencyCode: 'EUR',
Name: 'Urvish',
Description: 'First batch entry',
},
contactEntry2 = {
ProductID: 'KT-1982',
TypeCode: 'AD',
SupplierID: '0100000001',
TaxTarifCode: 1,
Category: 'Notebooks',
MeasureUnit: 'EA',
CurrencyCode: 'EUR',
Name: 'Urvish',
Description: 'Second batch entry',
};
oModel.setUseBatch(true);
oModel.create('/ProductSet', contactEntry1);
oModel.create('/ProductSet', contactEntry2);
oModel.refresh(true);
},

Looks like that you use the asynchronous operation for create but think that they are synchronous.
In order to fix this out, you can send these 2 create in one $batch request, but use the createEntry method of ODataModel, in order to use the submitChanges method, the callback of which, will be called once two of items are successfully created on the backend side (the below code example should be relevant for v2.ODataModel):
var oTableItemsBinding = oTable.getBinding("items");
// define the group ID, which will be used later on
var aCurrentDeferredGroups = oModel.getDeferredGroups();
oModel.setDeferredGroups(aCurrentDeferredGroups.concat("createProductGroup"));
// create two entries one by one, specifying the 'groupId' parameter
oModel.createEntry("/ProductSet", {
properties: contactEntry1,
groupId: "createProductGroup"
});
oModel.createEntry("/ProductSet", {
properties: contactEntry2,
groupId: "createProductGroup"
});
// send 2 requests in one $batch, passing the name of the 'groupId'
oModel.submitChanges({
groupId: "createProductGroup",
success: function() {
// no need to call refresh() as the model already does it by default (See "refreshAfterChange")
}.bind(this)
});
If your service does not support $batch requests, then you can still use the create method, but make use of it's success callback to be sure that the entry has been persisted in the backend.

Related

Filter duplicate values in select2 ajax call

I'm using select2 load remote data way to render results (50 at a time) from an api. The response of the api might have duplicate values in any page response.
I have tried formatting response but unfortunately the method is having access only to the current page data.
Below is my code,
jQuery('#items').select2({
minimumInputLength : 2,
placeholder : '-- Select Items --',
ajax : {
url : '/api/v1/items',
quietMillis : 200,
dataType : 'json',
data : function (term, page) {
return {
term : term,
page : page,
page_limit : 50
};
},
results : function(data, page) {
//Here I'm getting only current page data. How can i get previous page data to check for duplicate values.
}
}
});
So, how can I filter the response and eliminate duplicate values by checking against the data fetched so far.
Any help would be appreciated.
It would be better if you post an example of your code. Let's say you have some data with duplicated entries:
var rawData = [
{
id: 'AL',
name: 'Alaska'
},
{
id: 'GE',
name: 'Georgia'
},
{
id: 'WY',
name: 'Wyoming'
},
{
id: 'GE',
name: 'Georgia'
}
];
function clearDuplicates(data) {
var temp = {};
for (var i = 0; i < data.length; i++) {
temp[data[i]['id']] = data[i];
}
return Object.values(temp);
}
var clearData = clearDuplicates(rawData);
console.log(clearData);
See output: duplicated entry 'Georgia' is now in one record. There can be a lot of ways to eliminate duplicates. This is just one simple example.
UPDATE:
If you use pagination (infinite scroll) in Select2, every page request is sent separately and you have to process result data and eliminate duplicates manually. it can be done by processResults parameter. (See example)
In that case, easiest way would be:
Handle every page request in processResults
Store all results in a global variable
Eliminate duplicates as described in the example above
Return desired result
Return:
return {
results: <YOUR_FILTERED_DATA>,
pagination: {
//paginatioin params
}
}

correct way to use Stripe's stripe_account header from oauth with meteor

I'm trying to build a platform based on Meteor that uses Stripe Connect. I want to use the "preferred" authentication method from Stripe (Authentication via the Stripe-Account header, https://stripe.com/docs/connect/authentication) so that I can create plans and subscribe customers on behalf of my users. I cannot get it to work. I tried with a second params object, similar to the exemple in the documentation:
var stripeplancreate = Meteor.wrapAsync(Stripe.plans.create, Stripe.plans);
var plan = stripeplancreate({
amount: prod.price,
interval: prod.interv,
name: prod.name,
currency: prod.curr,
id: prod.id+"-"+prod.price+"-"+prod.curr+"-"+prod.interv,
metadata: { prodId: prod._id, orgId: org._id },
statement_descriptor: prod.descr
},{stripe_account: org.stripe_user_id});
but I get "Exception while invoking method 'createStripeProduct' Error: Stripe: Unknown arguments ([object Object]). Did you mean to pass an options object? See https://github.com/stripe/stripe-node/wiki/Passing-Options." which does not seem to accurately reflect the issue but prompted me to try adding stripe_account in the params object itself:
var stripeplancreate = Meteor.wrapAsync(Stripe.plans.create, Stripe.plans);
var plan = stripeplancreate({
amount: prod.price,
(...)
statement_descriptor: prod.descr,
stripe_account: org.stripe_user_id
});
I then get the following error: "Exception while invoking method 'createStripeProduct' Error: Received unknown parameter: stripe_account"
Any ideas? Has anybody managed to have Stripe Connect stripe_account authentication work with Meteor, especially with Meteor.wrapAsync(...)?
This should work for wrapAsync, HOWEVER check out my answer here for possible issues with wrapAsync - Wrapping Stripe create customer callbacks in Fibers in Meteor:
Here is also a great video on wrapAsync: https://www.eventedmind.com/feed/meteor-meteor-wrapasync
var createStripePlanAsync = function(shoppingCartObject, callback){
stripe.plans.create({
amount: shoppingCartObject.plan.totalPrice,
interval: shoppingCartObject.plan.interval,
name: shoppingCartObject.plan.planName,
currency: "usd",
id: shoppingCartObject.plan.sku //this ID needs to be unique!
}, function(err, plan) {
// asynchronously called
callback(err, plan);
});
};
var createStripePlanSync = Meteor.wrapAsync(createStripePlanAsync);
var myShoppingCart = {
customerInfo: {
name: "Igor Trout"
},
plan: {
totalPrice: 5000,
interval: "month",
name: "Set Sail For Fail Plan",
sku: "062015SSFF"
}
};
// Creates the plan in your Stripe Account
createStripePlanSync(myShoppingCart);
Later when you subscribe a customer to a plan you just refer to the plan via the id that you gave the plan when you first created it.
After much trying multiple things, for now, I just managed to get it working using the stripe-sync package instead of the "normal" one + wrapAsync.
try{
var plan = Stripe.plans.create({
amount: prod.price,
...
},{stripe_account: org.stripe_user_id});
}catch(error){
// ... process error
}

Data Model's "serialize" function not called on property "set"ting

Also asked on Sencha's site here
My data model's "serialize" function is not called when I call
model.set("<fieldName>", <newValue>);
Here's a fiddle
I'm pretty unclear on why the serialize function isn't called...am I missing something, or is this a bug?
(And here's the code from the fiddle)
Ext.application({
name : 'Fiddle',
requires: [
"Ext.data.Store"
],
launch : function() {
var store = Ext.create("Ext.data.Store", {
data: [{Id: 0, Name: "Bill", Props: "{foo: 2, bar:{pan:5}}"}],
fields:[
{name: "Id", type: "int"},
{name: "Name", type: "string"},
{name: "Props",
convert: function(value, record){
console.log("called convert");
return Ext.JSON.decode(value);
},
serialize: function(value, record){
alert("never getting called!! :(");
console.log("sure, i'll put log here too..not getting called though");
return Ext.JSON.encode(value);
}
}
]
});
console.log(store.getAt(0));
var rec = store.getAt(0);
var newProp = {rec:"junk", foo: "orange"};
console.log(newProp);
rec.set("Props",newProp);
}
});
Mappings from source content (JSON/XML) to business model (Ext.data.Model) are not automatically created in ExtJS's data model system. As such, another step is needed to produce this relationship using mapping/associationsor something similar.
I.e. The data model doesn't store the original JSON to read/write from, which is fine for most cases. When a JSON string needs to be updated via ExtJS, one solution is to, on the model, set
convertOnSet
to false, allowing for custom manipulation of the JSON string via extract/update functions on the data model.

How to display nested data items in FuelUX tree bootstrap plugin

I'm trying to implement the FuelUX tree plugin and I've followed the example so far but I need a nested structure. I'm assuming the tree plugin is capable of handling nested children? is this correct?
var treeDataSource = new TreeDataSource({
data: [
{ name: 'Test Folder 1', type: 'folder', additionalParameters: { id: 'F1' },
data: [
{ name: 'Test Sub Folder 1', type: 'folder', additionalParameters: { id: 'FF1' } },
{ name: 'Test Sub Folder 2', type: 'folder', additionalParameters: { id: 'FF2' } },
{ name: 'Test Item 2 in Folder 1', type: 'item', additionalParameters: { id: 'FI2' } }
]
},
{ name: 'Test Folder 2', type: 'folder', additionalParameters: { id: 'F2' } },
{ name: 'Test Item 1', type: 'item', additionalParameters: { id: 'I1' } },
{ name: 'Test Item 2', type: 'item', additionalParameters: { id: 'I2' } }
],
delay: 400
});
So far it seems to load the top level items into the opened folders rather than the nested data items. This is what the demo on their site also does but this doesn't seem as if its the desired interaction. Can anyone confirm if this is expected behaviour?
Can anyone point me to code where they've created a nested data tree using this plugin? Is there something really obvious I am missing?
I am actually in the process of writing a blog post on this very issue.
The solution I have developed is not for the faint-of-heart. The problem is that the folder objects do not support instantiation with child data. Also, adding children is no trivial task. I spun up a quick fiddle that you can pick through to get an idea of how to accomplish your goal. I am using this same solution only that my addChildren function calls out to an MVC route via AJAX and gets back a JSON object to populate the children dynamically.
You can literally, copy and paste the code from my fiddle and start using the addChildren function out-of-the-box.
I'm sorry for the lack of documentation about this - it needs to be improved for sure.
The idea is that you provide a dataSource when instantiating the tree control, and that data source should have a data function with the signature (options, callback). That data function will be called on control init to populate the root level data, and will be called again any time a folder is clicked.
The job of the data function is to look at the options parameter which is populated from the jQuery.data() on the clicked folder and respond with the data for that folder. The special case is the initial root folder data, where the options are populated from any jQuery.data() on the control's root div, which may or may not exist.
The jQuery.data() on folders is populated from the array of objects you provide in your data function's callback. You can see in this example https://github.com/ExactTarget/fuelux/blob/master/index.html#L184-L189 there is a property called additionalParameters but really you can provide any additional properties beyond the required name and type for you to use later (the next time your data function is called) to determine which folder was clicked and return the data for that folder.
Our current example returns the same static data for every folder, which is not the best example, so I do hope to improve this situation by either creating a tutorial myself or linking to one if someone beats me to it.
Following up on Adam's answer, here is an example that seems to accomplish what you want..
The data function for the DataSource can check to see if there is "sub" data passed via options:
DataSource.prototype = {
columns: function () {
return this._columns;
},
data: function (options, callback) {
var self = this;
if (options.search) {
callback({ data: self._data, start: start, end: end, count: count, pages: pages, page: page });
} else if (options.data) {
callback({ data: options.data, start: 0, end: 0, count: 0, pages: 0, page: 0 });
} else {
callback({ data: self._data, start: 0, end: 0, count: 0, pages: 0, page: 0 });
}
}
};
Demo on Bootply: http://www.bootply.com/60761

Process extjs store proxy data after data recieved

I am using extjs sencha store for storing data. I make a proxy call to a web-service to get data. I refresh the data using store.load() function.
I am looking to edit the data that is received before it is given to the grid.
I know about the load event, but this function is executed after the load is completed and data is populated with the current data.
listeners : {
'load' : function(store,records, options) {
}
},
I am looking to see how I can edit the returned data from web-service before it is assigned to the store. Basically data returned from my webservice is in different format than the format we give to extjs datagrid. So, want to do a data operation before we give to the grid. Hope we can do this.
Thx
Model mappings can help you do this. There is a conversion function that can be supplied as well. Here is the example from the docs:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{
name: 'firstName',
convert: function(value, record) {
var fullName = record.get('name'),
splits = fullName.split(" "),
firstName = splits[0];
return firstName;
}
},
'name', 'email',
{name: 'age', type: 'int'},
{name: 'gender', type: 'string', defaultValue: 'Unknown'}
]
});

Categories

Resources