Populating store with records parameter from proxy - extjs

In my store I am calling load on a store. It is hitting the server and getting a bunch of data, however my data is not in the records object.
Instead the data I want is in the operation.response object.
store.load({
params: postBody,
callback: function (records, operation, success) {
if (success) {
console.info('seccuess')
var decoded = Ext.decode(operation.response.responseText);
if(decoded.success && decoded.result.length > 0){
var results = decoded.result; //results are in record array here!!!
}
}
}
});
The records object is returning something that is not what I want.
All the records seem to be in the operation.response object (see results variable). I didn't write this code so I can't explain the reasoning behind this.
Bottom line : How do I inject/set/put these results into the store?
Is there something like this :
this.setData(results)
that I can call in the callback object? The proxy magic going on behind the scenes is trying to apply the records object onto my grid.

Related

JSON stored into an array not callable by specific index

I am trying to develop an app for my fantasy baseball league to use for our draft (we some kind of quirky stuff all the major sites don't account for) - I want to pull some player data to use for the app by using MLB's API. I have been able to get the response from MLB, but can't do anything with the data after I get it back. I am trying to store the JSON into an array, and if I console.log the array as a whole, it will give me the entire chunk of data, but if I try to call the specific index value of the 1st item, it comes back as undefined.
let lastName = 'judge';
let getData = new XMLHttpRequest;
let jsonData = [];
function getPlayer () {
getData.open('GET', `http://lookup-service-
prod.mlb.com/json/named.search_player_all.bam?
sport_code='mlb'&active_sw='Y'&name_part='${lastName}%25'`, true)
getData.onload = function() {
if (this.status === 200) {
jsonData.push(JSON.parse(this.responseText));
}
}
getData.send();
console.log(jsonData);
}
When I change the above console.log to console.log(jsonData[0]) it comes back as undefined. If I go to the console and copy the property path, it displays as [""0""] - Either there has to be a better way to use the JSON data or storing it into an array is doing something abnormal that I haven't encountered before.
Thanks!
The jsonData array will be empty after calling getPlayer function because XHR loads data asynchronously.
You need to access the data in onload handler like this (also changed URL to HTTPS to avoid protocol mismatch errors in console):
let lastName = 'judge';
let getData = new XMLHttpRequest;
let jsonData = [];
function getPlayer () {
getData.open('GET', `https://lookup-service-
prod.mlb.com/json/named.search_player_all.bam?
sport_code='mlb'&active_sw='Y'&name_part='${lastName}%25'`, true)
getData.onload = function() {
if (this.status === 200) {
jsonData.push(JSON.parse(this.responseText));
// Now that we have the data...
console.log(jsonData[0]);
}
}
getData.send();
}
First answer from How to force a program to wait until an HTTP request is finished in JavaScript? question:
There is a 3rd parameter to XmlHttpRequest's open(), which aims to
indicate that you want the request to by asynchronous (and so handle
the response through an onreadystatechange handler).
So if you want it to be synchronous (i.e. wait for the answer), just
specify false for this 3rd argument.
So, you need to change last parameter in open function as below:
getData.open('GET', `http://lookup-service-
prod.mlb.com/json/named.search_player_all.bam?
sport_code='mlb'&active_sw='Y'&name_part='${lastName}%25'`, false)
But from other side, you should allow this method to act asynchronously and print response directly in onload function.

im trying to update database record with function return Ionic, Back&

Hi I'm trying to update my database with function that returns a number
$scope.sum = function()
{
return $scope.inp + $scope.points;
};
this function will update the record in object points, column name and id 1:
$scope.addPoint = function() {
PointService.addPoint($scope.sum, 1)
.then(function(result) {
$scope.inp = 0;
getMyPoints();
});
}
addPoint = function(id,points)
{
return $http.put(getUrlForId(1),points,name);
}
the error is: Error details: Cannot convert type 'int' to 'System.Collections.Generic.Dictionary'
the data type of the field is Float.
Any idea what is wrong with the code?
you are passing function reference to PointService.addPointer(),
use this:
$scope.addPoint = function() {
PointService.addPoint($scope.sum(), 1) // NOT PointService.addPoint($scope.sum, 1)
.then(function(result) {
$scope.inp = 0;
getMyPoints();
});
}
this will execute your function and pass the output (id parameter) to addPoint function, further, for more safe side, you can return Number from $scope.sum() i.e.
$scope.sum = function()
{
return Number($scope.inp + $scope.points);
};
This looks like an issue with how you're contacting Backand. You use the following code to send your points over:
addPoint = function(id,points)
{
return $http.put(getUrlForId(1),points,name);
}
This is an older version of calling the Backand API that is manually constructing a PUT request, and putting "points" and "name" as the "Data" and "config" parameters to $http. With an object update via PUT, you'll need to provide the updates as an object. So if you wanted to update the points and the name of the object (and I'm doing some assuming based upon what I can tell from the code snippet above), you'd need to encapsulate these properties in an object that has the following general format:
{
"field_name_1":"new value_1",
"field_name_2":"new value_2",
etc ...
}
This should then be sent as the body of the request. So, for your code, change it to the following and see if this helps:
addPoint = function(id,points)
{
return $http.put(getUrlForId(1),{points: points, name: name});
}
To give more info on why you're seeing this particular error, Backand is depending on this JSON format in the body. Our platform should definitely do more validation (and I'll create a ticket for the devs to handle non-conforming input more gracefully), but at the moment we simply take the body of the request, convert it to a dictionary object, then begin the requested operation. As your code above sends only "1.0" as the body, this fails the conversion into a dictionary, causing the stack exception and the issue you are seeing.
As a note, we offer a new SDK that encapsulates these HTTP methods, performing the authentication header generation and HTTP messaging for you, providing promises to handle responses. You can find it on our Github page at https://github.com/backand/vanilla-sdk. To make the same call using the new SDK, the code would resemble the following:
backand.object.update("your object name", 1, {name: name, points: points})
.then(function(response){
console.log(response.data);
});

Understanding BackboneJS flow

I have been given a Project which is written entirely in Backbone.js, which I am supposed to change according to our specific needs. I have been studying Backbone.js for the past 2 weeks. I have changed the basic skeleton UI and a few of the features as needed. However I am trying to understand the flow of the code so that I can make further changes.
Specifically, I am trying to search some content on Youtube. I have a controller which uses a collection to specify the url and parse and return the response. The code is vast and I get lost where to look into after I get the response. I tried to look into views but it only has a div element set. Could someone help me to proceed. I wont be able to share the code here, but a general idea of where to look into might be useful.
Code Snippet
define([
'models/youtubeModelForSearch',
'coretv/config',
'libs/temp/pagedcollection',
'coretv/coretv'
],function( youtubeModelForSearch, Config, PagedCollection, CoreTV ) {
"use strict";
return PagedCollection.extend({
model: youtubeModelForSearch,
initialize: function() {
this.url = 'http://gdata.youtube.com/feeds/api/videos/?v=2&alt=json&max-results=20';
},
fetch: function(options) {
if (options === undefined) options = {};
if (options.data === undefined) options.data = {};
//options.data.cmdc = Config.getCMDCHost();
//CoreTV.applyAccessToken(options);
PagedCollection.prototype.fetch.call(this, options);
},
parse: function(response) {
var temp = response.feed
/*temp["total"] = 20;
temp["start"] = 0;
temp["count"] = 10; */
console.log(temp);
return temp.entry;
},
inputChangeFetch: function(query) {
this.resetAll();
if(query) {
this.options.data.q = query;
// this.options.data.region = Config.api.region;
//this.options.data.catalogueId = Config.api.catalogueId;
this.setPosition(0);
}
}
});
});
Let's assume your collection endpoint is correctly set and working. When you want to get the data from the server you can call .fetch() on you collection.
When you do this, it will trigger an request event. Your views or anybody else can listen to it to perform any action.
When the data arrives from the server, your parse function is called, it is set using set or reset, depending the options you passed along fetch(). This will trigger any event related to the set/reset (see the documentation). During set/reset, the data retrieved from your server will be parsed using parse (you can skip it, passing { parse: false }.
Right after that, if you passed any success callback to your fetch, it will be called with (collection, response, options) as parameters.
And, finally, it will trigger a sync event.
If your server does not respond, it will trigger an error event instead of all this.
Hope, I've helped.

how to get record from store without using load function in extjs4.1

I have the json response with totalCount Values. I am getting the totalCount value in a load function. I am creating store in controller before loading store If(totalCount>0). It is executing the else condition. Can anybody tell me how to load store and check the conditon?. Is it possible to get a record from a field without load function?
var totalCount=0;
store.load(
{
scope: this,
callback: function(records, operation, success) {
totalCount = records[0].data.totalCount
}
}
);
if (totalCount > 0) {
console.log("record found");
} else {
console.log("record not found");
}
The problem here is that the store.load function is asynchronous. That means your code immediately following the call to load will execute before the load function returns. Your callback function gets called much later than the if statements get executed.
To answer your actual question in the title of your post look in the API: http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.data.Store
Depending on what you need you can use any number of methods: .getRange() to get an array or .each() to immediately iterate over records.
It looks like your evaluation of totalCount is probably occurring before the load callback is executed. Since you initialize totalCount to 0 before the call to load the store, that's what the value is when you're evaluating it. Move the console logging into your callback function to verify this.

How to export grid to XLS in ExtJS4.0

Is there a simple way to export a grid data to XLS in ExtJS.
If not I am trying the following way.
I am trying to read the data store inside a controller. The datastore is already being used by the grid. I want to read the data on a button click and send it to server through AJAX. Later inside server I would retrieve the data and write to XLS. In this case what is the way I can read the data inside the controller?
enter code here
Ext.define("MyApp.controller.GridController", {
extend : 'Ext.app.Controller',
views: ['performance.grid.PerformanceGrid'],
models: ['GridModel'],
stores: ['GridStore'],
refs : [{
ref : 'mainTabPanel',
selector : 'portal > tabpanel'
}],
init : function() {
this.control({
'portal toolbar > button[itemId=xls]' : {
click : this.onAddTab
},
'portal toolbar > button[itemId=pdf]' : {
click : this.onAddPortlet
}
});
},
onAddTab : function(btn, e) {
// I want to read the datastore here and make an AJAX call
},
});
onAddTab: function(btn, e){
var store = // get the store reference probably doing Ext.getStore('the store');
var records = store.data.items.map(function(r){ return r.data });
// send it all to your server as you want to
// Ext.ajax.Request({
// url: 'the url',
// data: records,
// method: 'POST'
// });
});
I didnĀ“t test it but it have to work.
Good luck!
I think that process is not the best because you will have 3 payloads (data round trips that doesn't make any sense)
Your call your server method to get the data that will be populated into the grid.
The JSON object (containing the server data) will then travel again to the server
(THIS DOESN'T MAKE SENSE TO ME... WHY YOU WANT TO SEND DATA TO SERVER WHEN THE SERVER WAS THE SOURCE?? )
The server will process your object from JSON response and then create the document on the fly and send it back to server.
What I think you should do is the following:
Get data from server and bind your grid.
Get your store proxy URL and parse the method and extraParams so you know who served the grid and what you asked to the server.
Create a common method on server that receives a method and an array of parameters. Then inside this method make the logic so depending on the method, you call your data Repository (same repository where your first request got the data), process the document and send the file back to server.
This way you should have something like this:
webmethod(string method, object[] params) {
switch(method){
case "GetTestGridData":
// here you call your Repository in order to get the same data
GeneralRepo repo = new GeneralRepo();
var data = repo.GetTestGridData(object[0],object[1]);
break;
}
byte[] fileStream = Reports.Common.Generate(data, ExportType.PDF);
// response the stream to client...
}

Resources