How to set total records dynamically from the controller - extjs

Here is the problem,
Server responds with several records in JSON, which number is greater than grid pageSize parameter specified in the Store. The total number is not returning by a server in this JSON with data. The number of such records is known and could be different (this number should be requested from the server in another request). The total number is needed for the pagingtoolbar.
How to tell the proxy reader this number from the view controller?
The only workable solution I found is to override the Ext.data.reader.Json reader with the following code:
Ext.define('MyApp.custom.AnotherReader',{
extend: 'Ext.data.reader.Json',
alias : 'reader.anotherReader',
// разбираем ответ и записываем в store
getResponseData : function(response) {
var st = Ext.decode(response.responseText);
st.total = 5;
//console.log(st);
return st;
}
});
The problem is I cannot dynamically change this total parameter from the viewcontroller.
JSON 1:
[
{
"id":"1",
"user_id":"11",
},
{
"id":"2",
"user_id":"12",
},
{
"id":"3",
"user_id":"13",
},
{
"id":"4",
"user_id":"14",
},
{
"id":"5",
"user_id":"15",
}
]
JSON 2:
{
"records_count": "5"
}

You can do this inside your controller -
// some event handler/ or normal function inside your Controller that you'll call
somFunction: function() {
var me = this;
var store = Ext.getStore(<storeId>); // you can even pass the store
//instance as a parameter to this function
var reader = store.getProxy().getReader();
Ext.override(reader, {
getResponseData : function(response) {
var st = Ext.decode(response.responseText);
st.total = me.getValueYouWant();
return st;
}
});
}

Related

How can search JSON for a value key and return the nested data?

The below block is my JSON. The -KTYLrHDHt234rFDNHrm type hashes are generated by the supplied API of the client. I think they're using Firebase.
I am passing a query in the URL which contains the pageId for each of those nested objects.
Example https://cms.app.io/edit/Nike3243
But since the hash is auto generated how can I search through all the JSON and check if the pageId matches my Angular route and then only return the values of the same child.
{
"-KTYLrHDHtdq23423NHrm": {
"pageCreation": "10/8/2016, 14:14:22 PM",
"pageGallery": {
"slider_1_img": "http://",
"slider_2_img": "http://",
},
"pageId": "Nike13243",
"pageName": "Nike Campaign 1",
"store": "11"
},
"-KTYLrHDHtdqirFDNHrm": {
"pageCreation": "10/8/2016, 12:14:22 AM",
"pageGallery": {
"slider_1_img": "http://",
"slider_2_img": "http://",
},
"pageId": "Nike323243",
"pageName": "Nike Campaign 2",
"store": "12"
},
"-KTYLrHDHt234rFDNHrm": {
"pageCreation": "10/8/2016, 13:14:22 PM",
"pageGallery": {
"slider_1_img": "http://",
"slider_2_img": "http://",
},
"pageId": "Nike3243",
"pageName": "Nike Campaign 3",
"store": "13"
}
}
So I want to return only the data of Nike3243 but I want to return the store, the slider and the pageName. How can I do this since the KTYLrHDHt234rFDNHrm hash is something I will never know
cmsApp.controller('pages-edit', function ($scope, $http, $routeParams) {
var pageIdU = $routeParams.id;
$http.get(firebase_url+'cms/home.json'+randstatus).success(function(data) {
$scope.pages = data;
// this would be pageId = Nike3243
console.log(data.pageIdURI.pageName[pageId]);
});
});
Thanks
Assuming your object is called 'objTest', you could do something like this:
var strPageId = 'The page id to find', objFound;
for( var strKey in objTest ) {
var objTemp = objTest[strKey];
if ( objTemp['pageId'] == strPageId ) {
objFound = objTemp;
break;
}
}
if ( typeof objFound == "object" ) {
//Do something...object has been found!
}
I actually did this:
$.each(data, function (bb) {
var crossReference = data[bb].transId;
if (crossReference==pageIdUri) {
$scope.transNameEn = data[bb].transNameEn;
$scope.transNameArabic = data[bb].transNameArabic;
$scope.transCreation = data[bb].transCreation;
$scope.transModified = data[bb].transModified;
$scope.notes = data[bb].notes;
}
});
It may be easier for you to simply transform the data rather than perform this search over and over. You can loop through the data once and get it in the correct format.
I would do something like:
var recordLookup = {};
for (var id in records) {
var pageId = records[id].pageId;
recordLookup[pageId] = record[id];
recordLookup[pageId].originalId = id;
}
This way you can now easily look up any record by its page id. If you need to send the data back to the server in the original form you still have that original id and can do whatever you need to in order to get it in the proper format. This way you loop once or maybe twice, (once to make the lookup and once to revert at the end of your operation) rather than any time you need to get data out of your records.

MEAN stack - How do I retrieve a data subset based on user?

I'm retrieving datapoints by mongoose from a collection of the form:
{
"_id":"1",
"creator":
{"_id":"a",
"username":"aaa",
"name":"aaa"},
"comment":"",
"value":10,
"created":"2016-05-28T12:09:25.666Z"},
{
"_id":"2",
"creator":
{"_id":"b",
"username":"bbb",
"name":"bbb"},
"comment":"",
"value":100,
"created":"2016-05-28T09:13:18.361Z"}
...
Where each datapoint is defined by a Schema and creator is defined by a separate Schema.
I'm able to retrieve all datapoints via angular by using the resource query method:
$scope.find = function() {
$scope.datapoints = Datapoints.query();
};
I would now like to retrieve only those datapoints corresponding to the specific user (whose details are accessible through $scope.authentication.user).
Failed attempts include:
$scope.findByUser = function() {
user = $scope.authentication.user;
$scope.datapoints = Datapoints.query({creator:user});
};
or:
$scope.findByUser = function() {
Datapoints.query(function(result) {
$scope.datapoints = $filter('filter')(result, {creator: $scope.authentication.user});
});
or:
$scope.findByUser = function() {
$scope.datapoints = Datapoints.query();
$scope.datapoints = $filter('filter')($scope.datapoint, {creator: $scope.authentication.user});
};
Any help is appreciated. Thanks!!

Angular Resource update method with an array as a parameter

I have been googleing this for a few weeks with no real resolution.
I am sure someone will mark this a duplicate, but I am not sure it really is, maybe I am just being too specific, anyway here goes.
I am using angular in a node-webkit app that I am building. I have an api built in express and I am using MongoDB (#mongolab) with Mongoose for the DB.
I had this working fine as long as all of the data types were simple strings and numbers. but I had to restructure the data to use arrays and complex objects. After restructuring the data I was able to get post API calls to work fine, but I cannot get my PUT calls to work at all.
The data looks like this:
itemRoles was an array, but I thought it was throwing the error I am getting now, so I converted it back to a string.
itemStats is causing the problem. Angular is looking for an object, but itemStats is an array (I think anyway). itemStats used to be a string as well, but its easier to work with in my view if it is an array of objects with key:value pairs, which is why I altered it.
I should note I am new to MongoDB as well, first time using it.
{
"_id": {
"$oid": "55a10b9c7bb9ac5832d88bd8"
},
"itemRoles": "healer,dps",
"itemRating": 192,
"itemName": "Advanced Resolve Armoring 37",
"itemClass": "consular",
"itemLevel": 69,
"itemStats": [
{
"name": "Endurance",
"value": 104,
"_id": {
"$oid": "55a10b9c7bb9ac5832d88bda"
}
},
{
"name": "Willpower",
"value": 124,
"_id": {
"$oid": "55a10b9c7bb9ac5832d88bd9"
}
}
],
"__v": 0
}
The Mongoose Schema looks like this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//var stats = new Schema({
//name: String,
//value: Number
//});
var armoringSchema = new Schema({
itemType: String,
itemClass: String,
itemRoles: String,
itemLevel: Number,
itemName: String,
itemRating: Number,
itemStats: [{ name:String, value:Number}]
});
module.exports = mongoose.model('Armor', armoringSchema);
Express API Route:
/ on routes that end in /armors/:id
// ----------------------------------------------------
router.route('/armors/:id')
// get method omitted
// update the armoring with specified id (accessed at PUT http://localhost:8080/api/armors/:id)
.put(function(req, res) {
// use our armor model to find the armor we want
Armoring.findById({_id: req.params.id}, function(err, armor) {
if (err) {
return res.send(err);
}
for(prop in req.body) {
armor[prop] = req.body[prop];
}
// save the armor
armor.save(function(err) {
if (err) {
return res.send(err);
}
res.json({success:true, message: 'Armor updated!' });
});
});
})
Resource Factory:
swtorGear.factory('armoringFactory', ['$resource', function ($resource) {
return $resource('http://localhost:8080/api/armors/:id', {}, {
update: { method: 'PUT', params: {id: '#_id'}},
delete: { method: 'DELETE', headers: {'Content-type': 'application/json'}, params: {id: '#_id'}}
});
}]);
Route for editing:
.when('/edit/armor/id/:id', {
templateUrl: 'views/modelViews/newArmor.html',
controller: 'editArmorCtrl',
resolve: {
armoring: ['$route', 'armoringFactory', function($route, armoringFactory){
return armoringFactory.get({ id: $route.current.params.id}).$promise;
}]
}
})
Contoller (just the save method, the first part of the controller populates the form with existing data):
$scope.save = function(id) {
$scope.armor.itemStats = [
$scope.armor.stats1,
$scope.armor.stats2
];
$scope.armor.itemRoles = '';
if($scope.armor.role.tank) {
$scope.armor.itemRoles += 'tank';
}
if($scope.armor.role.healer) {
if($scope.armor.itemRoles != '') {
$scope.armor.itemRoles += ',healer';
} else {
$scope.armor.itemRoles += 'healer';
}
}
if($scope.armor.role.dps) {
if($scope.armor.itemRoles != '') {
$scope.armor.itemRoles += ',dps';
} else {
$scope.armor.itemRoles += 'dps';
}
}
console.log($scope.armor);
$scope.armor.$update(id)
.then(function(resp) {
if(resp.success) {
var message = resp.message;
Flash.create('success', message, 'item-success');
$scope.armors = armoringFactory.query();
} else {
var message = resp.message;
Flash.create('success', message, 'item-success');
}
});
}
Formatted data being sent via PUT method (from console.log($scope.armor) ):
Error on save:
I haven't seen nesting schemas in the way that you're doing it. Here's something to try (hard to say if this is it for sure, there's a lot going on):
var armoringSchema = new Schema({
itemType: String,
itemClass: String,
itemRoles: String,
itemLevel: Number,
itemName: String,
itemRating: Number,
itemStats: [{
name: String,
value: Number
}]
});
Also we need to pass in an object to $update instead of just a number. Change $scope.armor.$update(id) to $scope.armor.$update({id: id}).

Batch Update an array in mongoose object

My Schema is as below. A student can participate in any no. of events.and each Event can have any number of students.
Student{
name:String,
age:Number,
.
.
.,
events:{
type:
[
{type:Schema.ObjectId,
ref:'Event'}
]
}
}
Event{
title:String,
desc:String,
eventDate:Date,
participants:{
type:
[{
student: {type:Schema.ObjectId,
ref:'Student'},
status : String
}]
}
}
My requirement:
Every time,I create an event, I need to push all the participants of that event inside event object. and in turn, tag the event reference inside all the participants.
My code is
function handleTeamParticipants(eventObj, participants) {
Student
.find({
$or: [{
_id: participants[0].student._id
}, {
_id: participants[1].student._id
}]
})
.populate('events events.participants events.participants.student')
.exec(function(err, students) {
var studentLength = students.length,
result = [];
var saveAll = function() {
var doc = students.pop();
Student.populate(doc, {
path: 'events.participants.student',
model: 'Student'
}, function(err, student) {
student.events.push(eventObj);
student.save(function(err, saved) {
if (err) next(err); //handle error
result.push(saved);
if (--studentLength) saveAll();
else // all saved here
{
return res.status(200).send(eventObj);
}
});
});
};
saveAll();
});
}
This code is working.
So, this way, I get only the first two participants updated and in turn added to eventobj. But I want the find query to select all the participants.student._id
Please let me know the easy way to do it.
Thanks.
I used lodash method pluck.
lodash.pluck(< arrayObj >,< attribute >);
will give the list of attribute values in the arrayObj.
studentList = lodash.pluck(pariticipants,"student");
studentIdList = lodash.pluck(studentList,"_id");

passing data to a collection in backbone

So I am trying storing product types from a json file before trying to add them to a collection but am getting some strange results (as in I dont fully understand)
on my router page i setup a variable for cached products as well as product types
cachedProductTypes: null,
productType : {},
products : {},
getProductTypes:
function(callback)
{
if (this.cachedProductTypes !== null) {
return callback(cachedProductTypes);
}
var self = this;
$.getJSON('data/product.json',
function(data)
{
self.cachedProductTypes = data;
callback(data);
}
);
},
parseResponse : function(data) {
result = { prodTypes: [], products: [] };
var type;
var types = data.data.productTypeList;
var product;
var i = types.length;
while (type = types[--i]) {
result.prodTypes.push({
id: type.id,
name: type.name,
longName: type.longName
// etc.
});
while (product = type.productList.pop()) {
product.productTypeId = type.id,
result.products.push(product);
}
};
this.productType = result.prodTypes;
console.log( "dan");
this.products = result.products;
},
showProductTypes:function(){
var self = this;
this.getProductTypes(
function(data)
{
self.parseResponse(data);
var productTypesArray = self.productType;
var productList=new ProductsType(productTypesArray);
var productListView=new ProductListView({collection:productList});
productListView.bind('renderCompleted:ProductsType',self.changePage,self);
productListView.update();
}
);
}
when a user goes to the show product types page it runs the showProductsType function
So I am passing the products type array to my collection
on the collection page
var ProductsType=Backbone.Collection.extend({
model:ProductType,
fetch:function(){
var self=this;
var tmpItem;
//fetch the data using ajax
$.each(this.productTypesArray, function(i,prodType){
tmpItem=new ProductType({id:prodType.id, name:prodType.name, longName:prodType.longName});
console.log(prodType.name);
self.add(tmpItem);
});
self.trigger("fetchCompleted:ProductsType");
}
});
return ProductsType;
now this doesnt work as it this.productTypesArray is undefined if i console.log it.
(how am I supposed to get this?)
I would have thought I need to go through and add each new ProductType.
the strange bit - if I just have the code
var ProductsType=Backbone.Collection.extend({
model:ProductType,
fetch:function(){
var self=this;
var tmpItem;
//fetch the data using ajax
self.trigger("fetchCompleted:ProductsType");
}
});
return ProductsType;
it actually adds the products to the collection? I guess this means I can just pass an array to the collection and do not have to add each productType?
I guess this means I can just pass an array to the collection and do not have to add each productType?
Yes, you can pass an array to the collection's constructor, and it will create the models for you.
As far as your caching code, it looks like the problem is here:
if (this.cachedProductTypes !== null) {
return callback(cachedProductTypes);
}
The callback statement's argument is missing this - should be return callback(this.cachedProductTypes).

Resources