JMS Serializer ignores mappings for Knp Paginator - jmsserializerbundle

I have problem with exclusion of some KNP Paginator properties with JMS Serializer.
First, this is included in composer.json
...
"jms/serializer-bundle": "~0.13",
"knplabs/knp-paginator-bundle": "2.4.*#dev",
...
I'm paginating CrmContacts entity and exclusion policy for that entity works well. I also added yml file for KNP Paginator like this:
config.yml
jms_serializer:
metadata:
directories:
KNPPB:
namespace_prefix: 'Knp\\Bundle\\PaginatorBundle'
path: %kernel.root_dir%/Resources/serializer/Knp
inside app/Resources/serializer/Knp folder I've created Pagination.SlidingPagination.yml:
Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination:
exclusion_policy: ALL
properties:
items:
expose: true
access_type: public_method
accessor:
getter: getItems
type: array
serialized_name:
payload
currentPageNumber:
expose: true
serialized_name:
page
numItemsPerPage:
expose: true
serialized_name:
items
totalCount:
expose: true
serialized_name:
totalItems
and this is logic for returning serialized data:
public function getContactsAction(Request $request)
{
$limit = $request->query->getInt('l', 10);
$page = $request->query->getInt('p', 1);
$serializer = $this->get('jms_serializer');
$contacts = $this->getDoctrine()
->getManager()
->getRepository('AcmeContactsBundle:CrmContact')
->getContacts();
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$contacts,
$page,
$limit
);
return new Response(
$serializer->serialize(
$pagination,
'json',
SerializationContext::create()->setGroups(['Default'])
),
Response::HTTP_OK,
[
'Content-Type' => 'application/json',
]
);
}
Unfortunately, I'm getting all properties from Knp Paginator in response:
{
"currentPageNumber": 1,
"numItemsPerPage": 10,
"items": [
{
"id": 1,
...
},
{
"id": 2,
...
},
{
"id": 3,
...
}
],
"totalCount": 3,
"paginatorOptions": {
"pageParameterName": "page",
"sortFieldParameterName": "sort",
"sortDirectionParameterName": "direction",
"filterFieldParameterName": "filterField",
"filterValueParameterName": "filterValue",
"distinct": true
},
"customParameters": [],
"route": "acmeContactsGetContacts",
"params": [],
"pageRange": 5,
"template": "KnpPaginatorBundle:Pagination:sliding.html.twig",
"sortableTemplate": "KnpPaginatorBundle:Pagination:sortable_link.html.twig",
"filtrationTemplate": "KnpPaginatorBundle:Pagination:filtration.html.twig"
}

The properties that you want to map are owned by Knp\Component\Pager\Pagination\AbstractPagination.
You also want to hide the rest of properties, so you will have to configure both classes.
I've just tried the following and it's working for me.
app/config/config.yml
jms_serializer:
metadata:
directories:
KnpPaginatorBundle:
namespace_prefix: Knp\Bundle\PaginatorBundle
path: %kernel.root_dir%/config/serializer/KnpPaginatorBundle
KnpPager:
namespace_prefix: Knp\Component\Pager
path: %kernel.root_dir%/config/serializer/KnpPager
app/config/serializer/KnpPager/Pagination.AbstractPagination.yml
Knp\Component\Pager\Pagination\AbstractPagination:
exclusion_policy: ALL
properties:
items:
expose: true
access_type: public_method
accessor:
getter: getItems
type: array
serialized_name:
payload
currentPageNumber:
expose: true
serialized_name:
page
numItemsPerPage:
expose: true
serialized_name:
items
totalCount:
expose: true
serialized_name:
totalItems
app/config/serializer/KnpPaginatorBundle/Pagination.SlidingPagination.yml
Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination:
exclusion_policy: ALL
Don't forget to clear the cache before testing.
Hope this helps you.

Instead of serializing all the pagination object, try to serialize only the data and items, like this:
$result = array(
'data' => $pagination->getItems(),
'meta' => $pagination->getPaginationData());
return new Response(
$serializer->serialize(
$result,
'json',
SerializationContext::create()->setGroups(['Default'])
),
Response::HTTP_OK,
['Content-Type' => 'application/json',]
);

Related

Which class in AWS CDK have option to configure Dynamic partitioning for Kinesis delivery stream

I'm using kinesis delivery stream to send stream, from event bridge to s3 bucket. But i can't seem to find which class have the option to configure dynamic partitioning?
this is my code for delivery stream:
new CfnDeliveryStream(this, `Export-delivery-stream`, {
s3DestinationConfiguration: {
bucketArn: bucket.bucketArn,
roleArn: kinesisFirehoseRole.roleArn,
prefix: `test/!{timestamp:yyyy/MM/dd}/`
}
});
I have been working on the same issue for a few days, and have finally gotten something to work. Here is an example of how it can be implemented in CDK. In short, the partitioning has to be enables as you have done, but you need to set the key and .jq expression in the so-called processingConfiguration.
Our incomming json data looks something like this:
{
"data":
{
"timestamp":1633521266990,
"defaultTopic":"Topic",
"data":
{
"OUT1":"Inactive",
"Current_mA":3.92
}
}
}
The CDK code looks as following:
const DeliveryStream = new CfnDeliveryStream(this, 'deliverystream', {
deliveryStreamName: 'deliverystream',
extendedS3DestinationConfiguration: {
cloudWatchLoggingOptions: {
enabled: true,
},
bucketArn: Bucket.bucketArn,
roleArn: deliveryStreamRole.roleArn,
prefix: 'defaultTopic=!{partitionKeyFromQuery:defaultTopic}/!{timestamp:yyyy/MM/dd}/',
errorOutputPrefix: 'error/!{firehose:error-output-type}/',
bufferingHints: {
intervalInSeconds: 60,
},
dynamicPartitioningConfiguration: {
enabled: true,
},
processingConfiguration: {
enabled: true,
processors: [
{
type: 'MetadataExtraction',
parameters: [
{
parameterName: 'MetadataExtractionQuery',
parameterValue: '{defaultTopic: .data.defaultTopic}',
},
{
parameterName: 'JsonParsingEngine',
parameterValue: 'JQ-1.6',
},
],
},
{
type: 'AppendDelimiterToRecord',
parameters: [
{
parameterName: 'Delimiter',
parameterValue: '\\n',
},
],
},
],
},
},
})

Generate items in Ext.dataview.List from hasMany models the MVC way

I have a Blog model with hasMany Posts (and many other fields). Now I want to list these posts in a List-view like that:
[My post #1]
[My post #2]
[My post #3]
As far as the API described, I'm able to pass either a store or a data attribute to Ext.dataview.List. But I was not able to find out how to pass the hasMany records to the list so it will display an item for each of them.
Do I really have to create another store? Isn't it possible to configure my dataview to something like store: 'Blog.posts' or data: 'Blog.posts' or even records: 'Blog.posts'?
Extend the dataview.List to define the itemtpl to loop through the posts
itemTpl: new Ext.XTemplate(
'<tpl for="**posts**" >',
'<div>{TheBlogPost}</div>',
'</tpl>'
)
As #Adam Marshall said, this doesn't work as easy as I imagined.
Sencha autogenerates stores from associations if you know how to access them.
So you simply can switch out the list's store for the autogenerated "substore" when it has loaded.
This approach probably has some problems, e.g. when listpaging plugin is used, but it is quick.
Example:
MODELS
Ext.define('Conversation', {
extend: 'Ext.data.Model',
config: {
fields: [
],
associations:
[
{
type: 'hasMany',
model: "Message",
name: "messages",
associationKey: 'messages'
}
]
}
});
Ext.define('Message' ,
{
extend: "Ext.data.Model",
config: {
idProperty: 'id_message',
fields: [
{ name: 'text', type: 'string' },
{ name: 'date', type: 'string' },
{ name: 'id_message', type: 'int' },
{ name: 'me', type: 'int'} // actually boolean
]
}
}
);
JSON
[
{
"messages": [
{"id_message": 11761, "date": 1378033041, "me": 1, "text": "iiii"},
{"id_message": 11762, "date": 1378044866, "me": 1, "text": "hallo"}
]}
]
CONTROLLER
this.getList().getStore().load(
{
callback: function(records, operation, success) {
//IMPORTANT LINE HERE:
getList().setStore(Ext.getStore(me.getList().baseStore).getAt(0).messages());
},
scope: this
}
);
LIST-VIEW
{
flex: 1,
xtype: 'list',
itemId: 'ConversationList',
data: [],
store: 'ConversationStore',
baseStore: 'ConversationStore',
itemTpl:
' {[app.util.Helpers.DateFromTimestamp(values.date)]}<br><b>{name}</b>' +
' {[app.util.Helpers.fixResidualHtml(values.text)]} </div>' +
},

Dojo Gridx with JsonStore

I'm trying to connect Gridx grid to JsonStore. The code and data is bellow. The problem is that Gridx is rendered correctly but it says: No items to display. Anybody know what I'm doing wrong? Dojo and Gridx are the latest versions installed with cpm.
edit: there is no ajax requet to /test/ in the Firebug/Chrom development tools
structure: [
{ field: 'id', name: 'Id' },
{ field: 'title', name: 'Title' },
{ field: 'artist', name: 'Artist' }
],
store: new JsonRestStore({
idAttribute: 'id',
target: '/test/'
}),
Data returned by /test is like this:
{
identifier: "id",
label: "title",
items: [
{
id: 1,
title: "Title 1",
artist: "Artist 1"
},
{
id: 2,
title: "Title 2",
artist: "Artist 2"
},
...
}
Grid is created with:
this.grid = new Grid({
structure: structure,
store: store,
modules: [
Pagination,
PaginationBar,
//Focus,
SingleSort,
ToolBar
],
//paginationInitialPage: 3,
paginationBarSizes: [10, 25, 50, 100],
paginationBarVisibleSteppers: 5,
paginationBarPosition: 'bottom'
}, this.gridNode);
have you specified which cache to use? In your case it should be an Async cache.
require([
'gridx/core/model/cache/Async',
.....
], function(Cache, ...){
this.grid = new Grid({
cacheClass: Cache,
......
});
I've found that this happens when the server doesn't return the Content-Range header in the response. Apparently the store isn't smart enough to just count the items in the returned array...

How to use inner properties of a JSON response with Sencha Proxy

The JSONP proxy is largely working for me, but I need to set properties of a model based on some nested properties in the JSON response. I can't figure how to do this without extending the Reader class, but thought there might be an easier way that I'm just missing.
My Recipe model:
Ext.define('NC.model.Recipe', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'name', type: 'string' },
{ name: 'image', type: 'string' },
{ name: 'preparationText', type: 'string' },
{ name: 'ingredientsText', type: 'string' },
{ name: 'servings', type: 'string' }
]
}
});
My Store:
Ext.define('NC.store.Recipes', {
extend: 'Ext.data.Store',
config: {
model: 'NC.model.Recipe',
storeId: 'Recipes',
proxy: {
type: 'jsonp',
url: 'http://anExternalSite.com/api',
callbackKey: 'callback',
filterParam: 'text',
extraParams: {
type: 'Recipe'
},
reader: {
type: 'json',
idProperty: 'uuid',
}
}
}
});
The JSON format:
[
{
uuid: "/UUID(XXXX)/",
name: "Spicy Peanut Noodle Salad",
image: "http://someplace.com/noodle-salad.jpg",
properties: {
preparationText: "Make it all nice and stuff",
ingredientsText: "Heaps of fresh food",
servings: "serves 4",
}
},
{ ... },
{ ... }
]
I would like those 3 'properties' - preparationText, ingredientsText, and servings, to be placed in the model, but currently only id, name, and image are. What is the method to make this work? If it does involve extending the Reader class, some direction would be great.
Thanks.
You can change your code like this to access nested values
{ name: 'preparationText', type: 'string', mapping: 'properties.preparationText' },
This mapping path should start excluding the root element.

ExtJS4 - Load Store From Another Grid

I am trying to load a json store when I click on a particular row in another grid. Can anyone see what I am doing wrong here? In the ext-all.js the error comes back as data is undefined (from debugger).
Ext.define('Documents', {
extend: 'Ext.data.Model',
fields: [
{ name: 'index', type: 'int' },
{ name: 'path', type: 'string' }
]
});
var documents = new Ext.data.JsonStore({
model: 'Documents',
root: 'groupdocuments',
autoLoad: false
});
// in the Ext.grid.Panel
listeners: {
itemclick: function () {
var itemgroupid = rec.get('groupid');
Ext.Ajax.request({
url: '/GetDocuments',
params: { groupId: itemgroupid },
success: function (result) {
var jsondata = Ext.decode(result.responseText);
documents.loadData(jsondata);
}
});
}
}
// the sample json returned from url
// { "groupdocuments": [{ "index": 1, "path": "1.doc" }, { "index": 2, "path": "2.doc" }, { "index": 3, "path": "3.doc" }] }
it looks like you need to escape the path data. should be { path: "C:\\something\\" }
Also why not use the grid Grouping feature?
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.grid.feature.Grouping
In looking further it looks like the loaddata function is expecting an array. Not a json object with a rootdata object like you are giving it. change the listener to the following:
var jsondata = Ext.decode(result.responseText);
documents.loadData(jsondata.groupdocuments);
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Store-method-loadData
alternatively you should be able to use loadRawData with the full json object.
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Store-method-loadRawData