JsonP scriptTag extjs4.1 issue - cross-domain

i got the following server response:
callback({
"data": [
{
"id": "13_gnomodotiseis",
"id1": 13,
"title": "5/2009 ΓΝΜΔ ΕΙΣΑΠ 2009",
"text": "5/2009 ΓΝΜΔ ΕΙΣΑΠ ",
"model": "gnomodotiseis",
"body": "σίλει...",
"type": "text",
"history": "old",
"url": "",
"search_tag": "Γνωμοδοτήσεις",
"new_element": "true"
}
],
"dataset": 1 })
I have a store definition like this:
var baseUrl = 'http://localhost:8090/';
Ext.define('Ktimatologio.store.NewSingleBlockStore', {
extend: 'Ext.data.Store',
alias: 'widget.newsingleblockstore',
requires: ['Ktimatologio.model.NewSingleBlockModel'],
model: 'Ktimatologio.model.NewSingleBlockModel',
groupField: 'search_tag',
fields: [
{name:'id', mapping:'id'},
{name:'id1', mapping:'id1'},
{name: 'text', mapping: 'text'},
{name: 'title', mapping: 'title'},
{name: 'fek', mapping: 'fek'},
{name: 'date', mapping: 'date'},
{name: 'descr', mapping: 'description'},
{name: 'model', mapping: 'model'},
{name: 'body', mapping: 'body'},
{name: 'type', mapping: 'type'},
{name: 'history', mapping: 'history'},
{name: 'src', mapping: 'url'},
{name: 'search_tag', mapping: 'search_tag'},
{name: 'new_element', mapping: 'new_element'},
{name: 'new_table', mapping: 'new_table'}
],
autoLoad: true,
proxy: {
//type:'ajax',
type:'jsonp',
url: baseUrl + 'openbd/ktimatologio-final/resources/cfScripts/nea_stoixeia/GetNews.cfc?',
callbackKey: 'callback',
extraParams: {
method: 'jsonP'
},
reader:{
type: 'json',
root: 'data'
}
}
});
The url that i am seeing in firebug:
http://localhost:8090/openbd/ktimatologio-final/resources/cfScripts/nea_stoixeia/GetNews.cfc?&_dc=1345305032559&method=jsonP&page=1&start=0&limit=25&group=[{"property"%3A"search_tag"%2C"direction"%3A"ASC"}]&sort=[{"property"%3A"search_tag"%2C"direction"%3A"ASC"}]&callback=Ext.data.JsonP.callback2
Firebug gives me error: "ReferenceError: callback is not defined"
My questions are:
From where does Ext.data.JsonP.callback2 pops up in the url?
What am i missing here? How jsonP in Extjs4.1 works?
I really need help on this one.
Thank you in advance,
Tom
Greece

You are using the wrong function name in the response. If you look at the request url, you can see that it is sending in the function name that your response needs to call, and you need to use it in the response data: &callback=Ext.data.JsonP.callback2, so the response should call the function Ext.data.JsonP.callback2 instead of just plain callback. So in the case of your example, the server should be returning this instead as the response:
Ext.data.JsonP.callback2({ "data": [ { "id": "13_gnomodotiseis", "id1": 13, "title": "5/2009 ΓΝΜΔ ΕΙΣΑΠ 2009", "text": "5/2009 ΓΝΜΔ ΕΙΣΑΠ ", "model": "gnomodotiseis", "body": "σίλει...", "type": "text", "history": "old", "url": "", "search_tag": "Γνωμοδοτήσεις", "new_element": "true" } ], "dataset": 1 })
This is because callback=Ext.data.JsonP.callback2 was sent in the request.

Related

SuiteScript TypeError: Cannot read property "firstname" from undefined

I have a problem that's not making any sense to me. I have created a custom search and I am using the results from that search to addSelectOptions to a select field I have added.
However when trying to simply access a value within a nested object I am getting the error message: TypeError: Cannot read property "firstname" from undefined.
Here is the code:
var sfPlayersSearch = search
.create({
id: 'customsearch_pm_sf_players_search',
title: 'SF Players Search',
type: search.Type.EMPLOYEE,
columns: [
'entityid',
'firstname',
'lastname',
'custentity_pm_ws_sf_player',
],
filters: ['custentity_pm_ws_sf_player', 'is', 'true'],
})
.run()
.getRange(0, 100);
log.debug({ title: 'SF Players', details: sfPlayersSearch });
var player1ProxyField = form.addField({
id: 'custpage_pm_ws_sf_player_1_proxy',
label: 'Player 1 Proxy',
type: ui.FieldType.SELECT,
});
var player2ProxyField = form.addField({
id: 'custpage_pm_ws_sf_player_2_proxy',
label: 'Player 2 Proxy',
type: ui.FieldType.SELECT,
});
for (var i = 0; i < sfPlayersSearch.length; i++) {
log.debug({title: 'Result', details: sfPlayersSearch[i].values.firstname});
player1ProxyField.addSelectOption({ value: sfPlayersSearch[i], text: sfPlayersSearch[i].id });
}
JSON Object:
[
[
{
"recordType": "employee",
"id": "8",
"values": {
"entityid": "Artur X",
"firstname": "Artur",
"lastname": "X",
"custentity_pm_ws_sf_player": true
}
},
{
"recordType": "employee",
"id": "50",
"values": {
"entityid": "Darryl X",
"firstname": "Darryl",
"lastname": "X",
"custentity_pm_ws_sf_player": true
}
},
{
"recordType": "employee",
"id": "1983",
"values": {
"entityid": "Douglas X",
"firstname": "Douglas",
"lastname": "X",
"custentity_pm_ws_sf_player": true
}
},
{
"recordType": "employee",
"id": "86477",
"values": {
"entityid": "Paul X",
"firstname": "Paul",
"lastname": "X",
"custentity_pm_ws_sf_player": true
}
}
]
]
Any help greatly appreciated. I have tried doing .values || {}.firstname and this returns no error, but also no result.
Search.run().getRange() returns an array of Result objects. These are what you are iterating through in your for block. The Result object does not include values but rather includes methods for access the values getValue()) and text (getText()) of each result.
Change
log.debug({title: 'Result', details: sfPlayersSearch[i].values.firstname});.
to
log.debug({title: 'Result', details: sfPlayersSearch[i].getValue('firstname')});
While #krypton 's answer is correct for what you are doing you may find it useful to use Netsuite's JSONified version of search objects like what you see in your log.
If you were writing this as a library file where you might want to work in a Map/Reduce you can normalize the search result like
.getRange(0, 100)
.map(function(sr){
return JSON.parse(JSON.stringify(sr));
});
Now your original code for values.firstname would work.
Fun fact. If you are using SS 2.1 you can use let', const, and arrow functions:
const players = search.create()...
.getRange(0, 100)
.map(sr=>(JSON.parse(JSON.stringify(sr)));

No value passed to the slots but Original Value is passed in the bot

I am using Amazon lex with AWS lambda as a validation Codehook. When I was trying to pass a value with a response card dynamically generated, it is showing null value in the AppointmentTime Slot but the original value is showing value in slotDetails.
Here is the request sent through lex:
{
"messageVersion": "1.0",
"invocationSource": "DialogCodeHook",
"userId": "prwna44b91sbr4w7d2pwwva59anaqzqx",
"sessionAttributes": {
"store_id": "26",
"address": "Quark Atrium, A‐45, Phase VIII Extension,Industrial Focal Point,Sahibzada Ajit Singh Nagar, Punjab 160071,India",
"closingTime": "19:00:00",
"city": "Mohali",
"phone": "9718409751",
"bookingDateTime": "2018-05-27T21:25:46+05:30",
"openingTime": "10:00:00",
"state": "PB",
"email": "bhuvnesh.kumar#sourcefuse.com",
"zip_code": "44545"
},
"requestAttributes": null,
"bot": {
"name": "ScheduleRide",
"alias": "$LATEST",
"version": "$LATEST"
},
"outputDialogMode": "Text",
"currentIntent": {
"name": "BookAppointment",
"slots": {
"CustomerAgreement": null,
"DropLocationPrompt": "yes",
"PickupAddress": "Unnamed Road, Industrial Area, Sector 74, Sahibzada Ajit Singh Nagar, Punjab 140308, India",
"RequiredService": null,
"AppointmentTime": null,
"DropAddress": null,
"PhoneNumber": null,
"AppointmentDate": "2018-05-28"
},
"slotDetails": {
"CustomerAgreement": {
"resolutions": [],
"originalValue": null
},
"DropLocationPrompt": {
"resolutions": [
{
"value": "yes"
}
],
"originalValue": "yes"
},
"PickupAddress": {
"resolutions": [],
"originalValue": "Unnamed Road, Industrial Area, Sector 74, Sahibzada Ajit Singh Nagar, Punjab 140308, India"
},
"RequiredService": {
"resolutions": [],
"originalValue": null
},
"AppointmentTime": {
"resolutions": [
{
"value": "00:00"
},
{
"value": "12:00"
}
],
"originalValue": "14:00:00"
},
"DropAddress": {
"resolutions": [],
"originalValue": null
},
"PhoneNumber": {
"resolutions": [],
"originalValue": null
},
"AppointmentDate": {
"resolutions": [],
"originalValue": "28 may"
}
},
"confirmationStatus": "None"
},
"inputTranscript": "14:00:00"
}
Here is the request passed to the lex, see the AppointmentTime in the slots object, it is showing null and in the slotDetails object, it is showing value. Here is the array of buttons which i pass from the response card object:
[ { text: '1:00 PM', value: '13:00:00' },
{ text: '1:30 PM', value: '13:30:00' },
{ text: '2:00 PM', value: '14:00:00' },
{ text: '2:30 PM', value: '14:30:00' },
{ text: '3:00 PM', value: '15:00:00' },
{ text: '3:30 PM', value: '15:30:00' },
{ text: '4:00 PM', value: '16:00:00' },
{ text: '4:30 PM', value: '16:30:00' },
{ text: '5:00 PM', value: '17:00:00' },
{ text: '5:30 PM', value: '17:30:00' },
{ text: '6:00 PM', value: '18:00:00' },
{ text: '6:30 PM', value: '18:30:00' } ]
Here is the function of buildResponseCard:
function buildResponseCard(title, subTitle, options){
let buttons = null;
console.log(options);
let genericAttachments = [];
if (options != null){
buttons = [];
for(let i = 0; i < (options.length); i++){
buttons.push(options[i]);
if(i%3 === 2){
genericAttachments.push({
title,
subTitle,
buttons
});
buttons = [];
}
}
}
return {
version: 1,
contentType: "application/vnd.amazonaws.card.generic",
genericAttachments
};
}
The reason I want AppointmentTime slot value on slot object to be shown on is that whenever the value in the slot is invalid through validation, I will set it to null and will callback it through lambda function and i will not be able to callback the slotDetails object in the response.
Can anyone tell me how can i achieve this?
For the AMAZON.TIME built-in slot:
When a user enters an ambiguous time, Amazon Lex uses the slotDetails attribute of a Lambda event to pass resolutions for the ambiguous times to your Lambda function. ... In this case, the value in the slots map is null, and the slotDetails entity contains the two possible resolutions of the time.
Your input of "14:00:00" is not understood as an unambiguous time, and Lex tries to resolve it to either noon or midnight, which is obviously wrong. This is probably because the Lex Time slot is expecting only hours and minutes (hh:mm) but not seconds (hh:mm:ss).
So if it is possible for you, one solution is to remove the seconds digits from your time values. For example:
[ { text: '1:00 PM', value: '13:00' }, ... ]
However, if you must have the seconds in the time value, then you can simply find the time the user selected from the inputTranscript value and do your validation of it from there.
var userInput = event.inputTranscript;
EDIT:
Another option is to ignore Lex's suggested resolutions and get the slot-details original-value. Like this:
var timeValue = event.currentIntent.slotDetails.AppointmentTime.originalValue;
And then set the AppointmentTime slot yourself. Like this:
event.currentIntent.slots.AppointmentTime = timeValue;

Sails swagger api documentation

I am using sails in my node js application. And want to implement swagger api documentation. And I follow Swagger Sails JS document. I got the result from my api doc. And my expected result from api doc . I have write the route in router.js file like below
'post /login': {
controller: 'user/UserController',
action: 'login',
skipAssets: 'true',
//swagger path object
"get": {
"tags": [
"Users"
],
"description": "Get a login user data",
"parameters": [{
"email": "abc#gmail.com",
"password": "12345678y",
"deviceToken": "12345678y",
"deviceType": 2
}],
"responses": {
"200": {
"statusCode": 0,
"status": true,
"message": "string",
"result": {}
}
}
}
}
If I had write wrong in my routes. Then how to write the routes, so that I will get my expected result from api docs?
Thanks!
You can try using this.
And I suppose router file should be like this:
'post /login': {
controller: 'user/UserController',
action: 'login',
skipAssets: 'true',
swagger: {
methods: ["get"],
tags: ["Users"],
description: "Get a login user data",
parameters: [{
email: "abc#gmail.com",
password: "12345678y",
deviceToken: "12345678y",
deviceType: 2
}],
responses: {
'200': {
statusCode: 0,
status: true,
message: "string",
result: {}
}
}
}
}

Count objects in array in an object in Frisby

I am starting to learn FrisbyJS and trying to create some assertions.
I get an json that looks like this
[
{
"articles": [
{
"article": "123-123002",
"updated": "2016-10-20T14:57:25",
"sourced balance": [],
"balance": "50.00"
},
{
"article": "100-123001",
"updated": "2016-10-20T14:41:36",
"sourced balance": [],
"balance": "10.00"
}
],
"DistrictID": [],
"WarehouseID": "SebastiansWarehouse",
"SourceID": "1234",
"City": "Stockholm",
"WarehouseName": "Sebastians Warehouse",
"WarehouseType": "STORE"
}
]
And I want to:
1. count the number of article objects
2. verify that the number X in articles array has a variable with value "123-123002"
How can I do this in Frisby?
My code currently is:
var frisby = require('frisby');
frisby.create('Mekonomen RIF1')
.get('https://10.254.8.67:9443/INTERSHOP/rest/WFS/Mekonomen-MekB2BSE-Site/-/availability/sources/1234/warehouses/SebastiansWarehouse/products/',{ strictSSL: false})
.expectStatus(200)
.expectHeaderContains('content-type', 'application/json')
.expectJSON('?',{
articles: [],
DistrictID: [],
WarehouseID: "SebastiansWarehouse",
SourceID: '1234',
City: "Stockholm",
WarehouseName: "Sebastians Warehouse",
WarehouseType: "STORE"
}
)
.expectJSON('?.articles',{
articles: [],
DistrictID: [],
WarehouseID: "SebastiansWarehouse",
SourceID: '1234',
City: "Stockholm",
WarehouseName: "Sebastians Warehouse",
WarehouseType: "STORE"
}
)
.expectMaxResponseTime(500)
.toss();
you can include
.afterJSON(json){
//json.articles can be asserted here
//some more assertion on the response
}
which will parse the response and send it as an argument which can be asserted using simple javascript conditions, statements, loops etc.

UI layer pagination and sorting in extjs

I have my extjs application. As of now i am getting all my records from backend, full record set in 1 service request. I need to implement the pagination and sorting at UI level. Sorting seems be simple. How do i implement UI level pagination? Any example for this? I am getting 10-20k records so it is fine if i implement pagination at UI level? Can extjs6 handle the load?
I'd recommend you handle paging server-side. Right now you might only have 10-20k records, but what if it grows to 100k? or 1 million?
Take a look at this guide from Sencha: Grids - Paging. It explains a lot.
Good luck!
Sorting is implemented out of box. This is simple pagination example based on default ExtJs 6.2.0 application.
YourAppName.view.main.List
...
// bottom paging-bar definition. Use "tbar" for top bar, or define both.
bbar: {
xtype: 'pagingtoolbar',
displayInfo: true,
emptyMsg: 'No data to display',
items: ['->'],
prependButtons: true
}
...
items: [{
title: 'Home',
iconCls: 'fa-home',
layout: 'fit', // needed for scrolling
scrollable: true, // for scrollable items
items: [{
xtype: 'mainlist'
}]
}, {
...
YourAppName.store.Personnel
Ext.define('YourAppName.store.Personnel', {
extend: 'Ext.data.Store',
alias: 'store.banners',
autoLoad: true, // run ajax-query right after grid rendering
loadMask: true, // show preload image
pageSize: 100,
model: 'YourAppName.model.Person',
proxy: {
type: 'ajax',
url: '/personnel',
reader: {
type: 'json',
rootProperty: 'items',
totalProperty: 'total'
}
}
});
Create in app/model folder file Person.js with:
YourAppName.model.Person
Ext.define('YourAppName.model.Person', {
extend: 'Ext.data.Model',
fields: [
{ name: 'name', type: 'string', defaultValue: '' },
{ name: 'email', type: 'string', defaultValue: '' },
{ name: 'phone', type: 'string', defaultValue: '' }
]
});
As of store definition your web-server must be able to response on HTTP GET-request on URI /personnel with json like this:
{
"success": true,
"total": 20000,
"items": [
{ "name": "Jean Luc", "email": "jeanluc.picard#enterprise.com", "phone": "555-111-1111" },
{ "name": "Worf", "email": "worf.moghsson#enterprise.com", "phone": "555-222-2222" },
{ "name": "Deanna", "email": "deanna.troi#enterprise.com", "phone": "555-333-3333" },
{ "name": 'Data', "email": "mr.data#enterprise.com", "phone": "555-444-4444" }
...
]
}

Resources