Integration of webix tables and backbone - javascript

I am tying to integrate webix tables with a backbone collection as shown in the webix docs (http://docs.webix.com/desktop__backbone_collections.html) however it does not seem to work. The object sync call happens, but no data is loaded.
budgets = new Backbone.Budget.Collection(window.budget)
list =
width : 320
view : "datatable"
id : "budget_list"
backbone_collection : budgets
select : true
scroll : false
columns :[
{header : "Month", id: "budget_month"}
{header : "Year", id: "budget_year"}
{header : "Currency", id: "base_currency"}
]
on: {
onAfterRender : () ->
console.log("Sync ", #_settings)
#sync(#_settings.backbone_collection)
}

Calling .sync from the onAfterRender causes the problem, as sync causes re-rendering of datatable, which triggers new sync and it causes new re-rendering and etc.
To break this loop you can use webix.once which will guarantee that handler will be executed only once.
Check the updated snippet http://webix.com/snippet/5dd61a47

Its very possible that the server you are hitting 1) is not specifying 'Content-type: application/json' and this is rejected by the client on the response; and, or 2) doesn't response to the OPTIONS pre-flight thus throws up a CORS security block. Both are difficult to solve without access to the server.
Curl will not be subject to the CORS issue but a browser-based REST client will -- and thus best represent your issue.
Try using the Chrome advanced rest client with the URL and headers given in the UI.
And if you dont know the URL and header then sniff your requests when you run that UI.

Related

tanstack / react-query : queries being re-fetched even though they're cached & 'fresh'

I'm using react-query v3, and encountered this problem when implementing backend pagination:
I have this useQuery hook in charge of caching getJobs which might be called with filters/ sorting/ paginated query parameters.
useQuery(
['jobs', activePage, limit, search, statusQuery, sortByQuery?.sort_by, sortByQuery?.order_by],
() => HttpClient.getJobs(activePage, limit, search, statusQuery, sortByQuery?.sort_by, sortByQuery?.order_by),
{
retry: false,
staleTime: DATA_REFRESH_INTERVAL_MS,
refetchOnWindowFocus: false,
keepPreviousData: true, // This tells React-Query that this Query is part of a paginated component
},
)
on my httpClient I use axios along with qs where I send all parameters serialized with skipNulls set to true, so all null/ empty values won't be sent.
so for example, when the page loads, first request being sent is /api/jobs?page=1&limit=7&search=job_1
looking into query dev tools I realized that my queries are cached, but also noticed in the network tab that my queries are being re-fetched even though they're in 'fresh' mode (to my understanding, only 'stale' queries should be re-fetched).
why is that? It got me thinking that maybe i'm not using the query keys right.
would appreciate any help with best practices / examples/ explanations

How to use 'find' in Google Sheets API (Cocos Creator)

I am using Cocos Creator to build a web app that will communicate with google sheets.
I didn't manage to find a suitable client library (as highlighted in below link)
https://discuss.cocos2d-x.org/t/integrating-google-sheets-api/47920
And decided to go with the REST api using http requests.
However, I am unable to find documents that show exactly how to perform the requests i need.
UPDATE:
Updated the title as I realized my previous approach of condition check is meant for filter views, which i misunderstood it's use case.
However, i saw this video showing that you can use the 'find' function that will return the cell grid, which is exactly what i'm looking for.
https://youtu.be/yPQ2Gk33b1U?t=348
I would like to know how to construct the request string to perform this call on the REST api using http request.
Previously:
As the title says, I need a condition check to for searching my sheet and return the cell that has the exact match for a given string.
This link documents that such conditions exist but does not show how to execute it with http request
https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other
I've found this post that is performing something very similar to what I wish to request, using FilterCriteria and Condition.
Looking for examples how to use the Google Sheets API FilterCriteria object
However, he is using the C# client library but is there any that I can use for Cocos Creator? As such, I have to perform this with REST using Http Request, and I have no leads on how to construct the request string.
var http = require('http');
var obj = {
'key' : 'MY_API_KEY'
}
var filters = {
'dataFilters': [
{
'Condition' : {
'type' : 'TEXT_EQ',
'values' : [{ 'userEnteredValue' : 'string_to_match' }]
},
}
]
}
var filtersStr = JSON.stringify(filters);
http.Get('MY_GOOGLE_SHEET_ID:getByDataFilter' + filtersStr, obj, function(responseJson)
{
console.log(responseJson);
});
Above code is something i attempted, but you bet it is not working.

Liferay 7: Retrieved custom field value using javascript api jsonws return java.lang.NullPointerException

I'm very new to liferay, I've created a page custom field using 'control panel > configuration > custom fields > page'. My goal is to retrieve the value from the page custom field and display the value in my custom portlet. One of the methods I've tried is using ExpandoValue/get-data API from the liferay json web service and this API is generated from localhost:8080/api/jsonws. Below is the generated javascript API:
Liferay.Service(
'/expandovalue/get-data',
{
companyId: themeDisplay.getCompanyId(),
className: 'com.liferay.portal.model.Page',
tableName: 'CUSTOM_FIELDS',
columnNames: 'pageDetail',
classPK: themeDisplay.getUserId()
},
function(obj) {
console.log(obj);
}
);
However, this api throws me an error: java.lang.NullPointerException. I'm thinking that this error occurs due to the permission given to the custom field. So, I've ticked View and Update permissions for Guest. But the issue persists.
My question is what triggered this error and how to fix it and is there any other solution I can use to retrieve the value from the page custom field?
Thanks in advance.
Edit
I had misunderstanding in assigning the attributes for the api and here is the new api as suggested by Olaf.
Liferay.Service(
'/expandovalue/get-data',
{
companyId: 20115,
className: 'com.liferay.portal.kernel.model.Layout',
tableName: 'CUSTOM_FIELDS',
columnName: 'details',
classPK: themeDisplay.getLayoutId()
},
function(obj) {
console.log(obj);
}
);
It works fine. However it only took the default value but not the value assign for that particular pages.
If memory serves me right, the stock remote API can't be used by unauthenticated users, but requires at least a logged in user (on top of the regular permissions of course).
You can test for this by accessing the API from logged in accounts with the same permissions. If it works there, then this is what you're running into.
However, when I interpret the call in your question correctly, the current user id would be the primary key for the custom field that you're looking at (looking at your classPK value). For a custom field on the page, I'd have expected a page id (layoutId in Liferay-API-terms). And while I'm seeing this, I notice com.liferay.portal.model.Page in your snippet. I've not seen that class, and pages can rather be found in com.liferay.portal.kernel.model.Layout (Assuming Liferay 7.1)
This makes me wonder what you're trying to achieve here - are you rather looking for a user-specific field (that would then be a custom field on the user) or really a page-specific field? Anyways - as this is an answer, not a comment, it might give enough hints to try out and come closer to a solution.

AngularJs bookmarkable url and query parameters

I'm trying to fix one mistake which one of the previous developer has did. Currently in project we have half-bookmarkable pages. Why half? Because if token has expired user will be redirect to resourse where he has to provide his credentials and on success he will be redirect to previous resource which he has used before. Sounds good for now. The problem here is next, some of resources have server side filtering and highly complicated logic which comes in the end to the one object like this:
param = {
limit: 10,
offset: 0,
orderBy: 'value',
query: 'string query can include 10 more filters'
};
then thru the service it sends a request to the end point
var custom = {};
function data(param) {
custom.params = param;
return $http.get('/data_endpoint', custom)
.then(function (response) {
return response.data;
});
From this part request works fine and response is correct but url isn't. User cannot store current url with search params because url doesn't have it and if user will try to get back to previous page with applied filters he won't be able to do that.
Also there is interceptor in this application, which add one more query param to every api request, because every api request requires some specific validation. This param is always the same.
I have tried to add $location.search(param) exactly to this data service but it breaks the app with infinity loop of login / logout looping, because interceptor stops working and all other request are sending without special query param
Then I thought to add this params inside interceptor like this:
config.params.hasOwnProperty('query') ? $location.search(config.params) : $location.search();
But it still breaks app to infinity loop.
This method adds query to url but doesn't allow to modify it, so if user applied additional filtering, it doesn't send new modified request but sends old one.
if (config.params.hasOwnProperty('query')){
for (var key in config.params){
$location.search(key, config.params[key])
}
}
That's why I decided to ask question here, probably somebody gives an advice how to solve this problem. Thanks in advance.

Duplicated rows when sorting dgrid 0.3.6

I've been using dgrid 0.3.2 along with JsonRest to display tables of data. Recently, I've been looking at upgrading to dgrid 0.3.6 or 0.3.7. Things work mostly the same, but it seems with the newer versions of dgrid that, if the user clicks a column header to sort fast enough, the grid will start displaying duplicate rows. I’ve verified that the response JSON and range are correct, and this didn’t seem to happen when we used dgrid 0.3.2.
Here’s a simple test case that reproduces the problem, and mimics how we set up our grid and store. Am I doing something wrong? If I don’t wrap the JsonRest in a Cache, I don’t get this issue, so I’m sure the problem is there, but I’m unsure about the performance ramifications of not caching the JSON response.
<!doctype html>
<html>
<head>
<%
String dgridVer = request.getParameter("dgridVer");
if (dgridVer==null) { dgridVer = "0.3.6"; }
%>
<script type="text/javascript">
var dojoConfig = {
isDebug: true,
baseUrl: 'dojo',
packages: [
{ name: 'dojo', location: 'dojo' },
{ name: 'dijit', location: 'dijit' },
{ name: 'dojox', location: 'dojox' },
{ name: 'dgrid', location: 'dgrid-<%=dgridVer%>' },
{ name: 'put-selector', location: 'put-selector' },
{ name: 'xstyle', location: 'xstyle' },
{ name: 'datagrid', location: '../datagrid' }
]
};
</script>
<script src="dojo/dojo/dojo.js"></script>
</head>
<body>
Try sorting a column as fast as you can. Look for duplicated rows.<br>
Using dgrid version: <%=dgridVer %><p>
<div id='gridDiv'></div>
<script>
require(['dgrid/Grid', 'dgrid/extensions/Pagination', 'dojo/store/JsonRest',
'dojo/store/Cache', 'dojo/store/Memory', 'dojo/_base/declare', 'dojo/domReady!'],
function(Grid, Pagination, JsonRest,
Cache, Memory, declare) {
var columns = [
{ field: "first", label: "First Name" },
{ field: "last", label: "Last Name" },
{ field: "age", label: "Age" }
];
var store = new JsonRest({
target: 'testData.jsp',
sortParam: "sortBy"
});
store = Cache(store, Memory());
var grid = new (declare([Grid, Pagination]))({
columns: columns,
store: store,
loadingMessage: 'Loading...',
rowsPerPage: 4,
firstLastArrows: true
}, 'gridDiv');
});
</script>
</body>
</html>
Check the default implementation of Cache.js, especially the query and queryEngine functions. By default they always get first to the master store, which in your case is the JsonRest store. Only after the data has been loaded, the caching store is updated (in your case the Memory store).
Now, if you check function _setSort in DGrid List.js file, and function refresh in DGrid OnDemandList.js you'll sill see that by default DGrid calls the query method of the current store to obtain the new list of items sorted differently. In your case that store is the dojo/store/Cache.
So, summing up, when the user clicks the column to sort, DGrid queries the Cache, which in turn queries JsonRest, which in turns queries the server, which then returns new data, which then the Cache stores in the Memory store.
You can actually confirm this for example with Firebug (a Firefox extension). In my case whenever I tried to sort, Firebug was showing a new request to the server to obtain new data.
This makes sense when there are lots of rows because DGrid is designed to load only the first batch of rows and then update the grid when user scrolls down. When the sort is changing, the first visible batch of rows may be different and may not be loaded yet, so DGrid must load them first.
But in my case the Json request was returning all data during a single request. I didn't like the default implementation and implemented my own caching store which doesn't require a trip to the server when changing the sorting. I can't share the implementation now but will try to do when I have some time to tidy up the code.
As for now you shouldn't notice any performance problems if you switch to JsonRest store only (considering that when changing the sorting there is the trip to the server anyway).
I am not sure what causes the specific problem of duplicated rows, but I remember seeing it too when my caching store wasn't implemented properly (it had something to do with deferred requests when loading data If I recall correctly). You can try to debug it by adding (again with Firebug) breakpoints in the get and query functions of the Cache store. My bet is that DGrid tries to load particular rows with the get method (which hits the cache) while the query request is still loading data from the server after user changed the sorting. But I may be wrong so please try to confirm it first if you can.

Categories