How to use nested maps in Dart? - dart

I am trying to use Dart alongside a api for a school system i have reverse engineered and I'm trying to implement it in a library, when using dio to send a request it is converted to a map (the output of the api is json i think) but it is nested and I’m not sure on how to work with them.
This is the code i have written
class StudentClient{
String sessionID;
StudentClient(this.sessionID);
Future<Map> basicInfo() async {
var dio = Dio();
dio.options.headers["Authorization"] = "Basic $sessionID";
Response loginRequest = await dio.get(
'https://www.classcharts.com/apiv2student/ping',
options: Options(contentType: Headers.formUrlEncodedContentType),
);
assert(loginRequest.data is Map);
Map<dynamic, dynamic> request = loginRequest.data;
return request;
}
and the (censored) output
{success: 1, data: {user: {id: 696969, name: Foo Bar, first_name: Foo, last_name: Bar, avatar_url: https://asdsdsdsd/26.0.0/img/faces/default.png, display_behaviour: true, display_parent_behaviour: false, display_homework: true, display_rewards: true, display_detentions: true, display_report_cards: true, display_classes: false, display_announcements: true, display_attendance: false, display_attendance_type: none, display_attendance_percentage: true, display_activity: true, display_mental_health: false, display_mental_health_no_tracker: false, display_timetable: true, is_disabled: false, display_two_way_communications: true, display_absences: false, can_upload_attachments: false, display_event_badges: false, display_avatars: false, display_concern_submission: false, display_custom_fields: false, pupil_concerns_help_text: , allow_pupils_add_timetable_notes: false, detention_alias_plural_uc: Detentions, announcements_count: 0, messages_count: 0, pusher_channel_name: Pupil_dfghfghhghfghfghfghfghfghfghfghfghfgh, has_birthday: true, has_new_survey: false, survey_id: null}}, meta: {version: 26.0.0}}
Any help would be appreciated!

Related

in Cesium, Why the request of 'Cesium/Workers/TerrainEncoding.js' is accidental?

const map = new Cesium.Viewer('map-3d', {
homeButton: false, // 关闭主页视角按钮
animation: false, // 关闭左下角动画组件
baseLayerPicker: true, // 关闭底图图层切换组件
geocoder: false, // 关闭搜索定位
timeline: false, // 关闭时间线部件
navigationHelpButton: false, // 关闭右上角导航帮助按钮
navigationInstructionsInitiallyVisible: false, // 不显示提示
infoBox: false,
selectionIndicator: false,
sceneModePicker: false, // 关闭二三维切换
scene3DOnly: true, // 只渲染 3D,节省资源
skyBox: false, // 关闭天空
skyAtmosphere: false, // 关闭大气
fullscreenElement: document.getElementById('map-container'), // * 要全屏的元素
})
const terrainProvider = new Cesium.CesiumTerrainProvider({
url: 'xxxx',
})
map.terrainProvider = terrainProvider
the problem details:
because of the request of Cesium/Workers/TerrainEncoding.js is accidental, result in my globe is the pure black globe and can not use normally.
please tell me the possible reason that cause it.

Fetch twin from Azure device sdk

I need to just get the twin of a device using the Azure device sdk for node.js.
I did used the Client clode as below:-
import { Client } from 'azure-iot-device';
import { Mqtt } from 'azure-iot-device-mqtt';
await client.setOptions(options);
await client.open();
const twin = await client.getTwin();
The issue is the twin returned doesn't have the device twin fields but other fields like below:-
{
_events: [Object: null prototype] { newListener: [Function: bound ] },
_eventsCount: 1,
_maxListeners: undefined,
_transport: Mqtt {
_events: [Object: null prototype] {
error: [Function],
connected: [Function],
disconnect: [Array],
message: [Function],
twinDesiredPropertiesUpdate: [Function: bound ]
},
_eventsCount: 5,
_maxListeners: undefined,
_mid: '',
_firstConnection: false,
_authenticationProvider: X509AuthenticationProvider { type: 0, _credentials: [Object] },
_mqtt: MqttBase {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
mqttProvider: [Object],
_onTheWirePublishes: [OnTheWireMessageContainer],
_fsm: [constructor],
_options: [Object],
_config: [Object],
_mqttClient: [MqttClient],
[Symbol(kCapture)]: false
},
_twinClient: MqttTwinClient {
_events: [Object: null prototype],
_eventsCount: 1,
_maxListeners: undefined,
_pendingTwinRequests: {},
_mqtt: [MqttBase],
_topicFsm: [BehavioralFsm],
_responseTopic: [Object],
_desiredPropertiesUpdatesTopic: [Object],
[Symbol(kCapture)]: false
},
_fsm: constructor {
initialState: 'disconnected',
states: [Object],
eventListeners: [Object],
namespace: 'fsm.2',
useSafeEmit: false,
hierarchy: {},
pendingDelegations: {},
_stamped: true,
inputQueue: [],
targetReplayState: 'connected',
state: 'connected',
priorState: 'connecting',
priorAction: 'connected.getTwin',
currentAction: '',
currentActionArgs: undefined,
inExitHandler: false
},
_topicTelemetryPublish: 'devices/amidha/messages/events/',
_topics: { method: [Object], message: [Object] },
_userAgentString: 'azure-iot-device/1.17.1 (node v12.18.0; Ubuntu 18.04; x64)',
[Symbol(kCapture)]: false
},
_retryPolicy: ExponentialBackOffWithJitter {
_errorFilter: DefaultErrorFilter {
ArgumentError: false,
ArgumentOutOfRangeError: false,
DeviceMaximumQueueDepthExceededError: false,
DeviceNotFoundError: false,
FormatError: false,
UnauthorizedError: false,
NotImplementedError: false,
NotConnectedError: true,
IotHubQuotaExceededError: false,
MessageTooLargeError: false,
InternalServerError: true,
ServiceUnavailableError: true,
IotHubNotFoundError: false,
IoTHubSuspendedError: false,
JobNotFoundError: false,
TooManyDevicesError: false,
ThrottlingError: true,
DeviceAlreadyExistsError: false,
DeviceMessageLockLostError: false,
InvalidEtagError: false,
InvalidOperationError: false,
PreconditionFailedError: false,
TimeoutError: true,
BadDeviceResponseError: false,
GatewayTimeoutError: false,
DeviceTimeoutError: false,
TwinRequestError: false
},
immediateFirstRetry: true,
normalParameters: ExponentialBackoffWithJitterParameters {
c: 100,
cMin: 100,
cMax: 10000,
ju: 0.25,
jd: 0.5
},
throttledParameters: ExponentialBackoffWithJitterParameters {
c: 5000,
cMin: 10000,
cMax: 60000,
ju: 0.25,
jd: 0.5
}
},
_maxOperationTimeout: 240000,
desiredPropertiesUpdatesEnabled: false,
properties: {
reported: { update: [Function: update], '$version': 1 },
desired: { '$version': 1 }
},
[Symbol(kCapture)]: false
}
I don't want to listen the twin change events that I can do easily by using above object using twin.on. I need to just get the current twin of the device. Is it possible?
After reading your comments it seems you are expecting some values to be there that just aren't available to the device (when you use the device SDK). The device can read and receive updates on desired properties and read/write to reported properties, the rest is unavailable.
In a comment, you mentioned you want to find the deviceScope in the twin, but that isn't available to the device SDK. You would need the service SDK for that.
When you print the result of const twin = await client.getTwin();, what you see is an object with helper methods to subscribe to desired property changes and patching new reported properties. Like Mark stated in his question, the properties of your twin are included in this object as well.
The current twin is in the JSON you posted. See the section properties:
properties: {
reported: { update: [Function: update], '$version': 1 },
desired: { '$version': 1 }
},
The twin you posted is empty.
Above is not feasible to get the whole twin not just the desired and reported properties from device IoT sdk and that has been confirmed by Azure too. Check here.
The link also has a solution to assign parent child relationship between the leaf and the edge device.

VSCode always trim trailing space (or format) on save

My vscode always format js code on save, here is my settings, but it didn't work:
"editor.insertSpaces": true,
"editor.renderWhitespace": "none",
"typescript.check.workspaceVersion": false,
"window.zoomLevel": 1,
"editor.cursorStyle": "block",
"typescript.check.tscVersion": false,
"editor.cursorBlinking": "blink",
"editor.lineNumbers": "relative",
"workbench.activityBar.visible": false,
"vim.useCtrlKeys": false,
"files.trimTrailingWhitespace": false,
"editor.trimAutoWhitespace": false,
"eslint.autoFixOnSave": false,
"editor.formatOnSave": false
Something wrong?

jqGrid: Sending param with dataUrl

I'm trying to create a dependent dropdown box. 'element' is dependent on 'grouping'.
My ajaxSelectOptions function seems to work, as 'temp' is passed, but then it isn't used by 'populate_element'. How can I use the 'temp' as my parameter :id?
My grid:
jQuery(document).ready(function(){
var lastsel;
var grid = jQuery("#list").jqGrid({
url:'codes/get_data.xml',
datatype: 'xml',
mtype: 'GET',
colNames:['ID', 'Version', 'Grouping', 'Element', 'Name'],
colModel:[
{name: 'id', index: 'id', hidden: true, editable: false },
{name: 'version', index: 'version',editable: true, editrules:{number:true}, cellEdit: true, search:true },
{name: 'grouping', index: 'grouping', editable: true, edittype: 'select', editoptions: {dataUrl: 'codes/populate_grouping.html'} },
{name: 'element', index: 'element', editable: true, edittype: 'select' }
],
pager: '#pager',
rowNum:200,
rowList:[50,100,200],
sortname: 'id',
sortorder: 'asc',
viewrecords: true,
height: 500,
scrollrows: true,
rownumbers: false,
caption: 'GL Codes',
editurl: 'codes/post_data.xml',
onSelectRow: function(id){
$("#list").setColProp('element', {editoptions: { dataUrl: 'codes/populate_element.html' }});
if(id && id!==lastsel){
$('#list').restoreRow(lastsel);
lastsel=id;
}
$('#list').editRow(id,true);
},
ajaxSelectOptions: {
data: {
temp: function(temp){
return grid.jqGrid('getGridParam', 'selrow')
}
}
}
});
Here is my error message:
Started GET "/codes/populate_element.html?temp=4" for 127.0.0.1 at 2012-09-27 17:18:33 +1200
Processing by CodesController#populate_element as HTML
Parameters: {"temp"=>"4"}
Completed 500 Internal Server Error in 1ms
ActiveRecord::RecordNotFound (Couldn't find Code without an ID):
app/controllers/codes_controller.rb:73:in `populate_element'
Update
I established that it was actually just a ruby syntax error in calling the param, rather than a jqGrid problem. For reference, I ended up calling it like so ... #code = Code.where(["id = ?",params[:temp]]).first
I think the problem is that you use wrong ids for the rows of grid. The error exist during filling of the grid. The most easy way to fix the problem will be to add key: true property to the definition of the 'id' column in colModel. In the case the value from the column id will be used as the rowid: the value of id attribute of rows (<tr>) of the grid.

How can I use a custom sortFunction with a Grails gui:datatable tag?

I have a datatable in Grails with several sortable columns. Unfortunately, the sort is case-sensitive by default, such that "Zed" is shown before "alice". So I want to add a custom case-insensitive sort function. I'll start by sorting the username column in this manner.
I have read about the sortOptions and sortFunction at http://developer.yahoo.com/yui/datatable/ but I can't seem to get it to work.
I added the following JavaScript to list.gsp:
var caseInsensitiveSortFunction = function(a, b, desc, field) {
// See http://developer.yahoo.com/yui/datatable/ and look for 'sortFunction'
// Set this function name as the sortFunction option
// Deal with empty values
if (!YAHOO.lang.isValue(a)) {
return (!YAHOO.lang.isValue(b)) ? 0 : 1;
} else if (!YAHOO.lang.isValue(b)) {
return -1;
}
return YAHOO.util.Sort.compare(String(a).toLowerCase(), String(b).toLowerCase(), desc);
};
And here is the datatable definition on that same page:
<gui:dataTable id="userTable"
controller="user" action="listJSON"
rowsPerPage="20"
sortedBy="username"
columnDefs="[
[key:'username', label:'Username', resizeable: false, sortable: true, sortOptions: { sortFunction: 'caseInsensitiveSortFunction' }],
[key:'email', label:'Email', resizeable: false, sortable: true],
[key:'firstName', label:'First Name', resizeable: false, sortable: true],
[key:'lastName', label:'Last Name', resizeable: false, sortable: true],
[key:'enabled', label:'Enabled', resizeable: false, sortable: true],
[key:'accountLocked', label:'Locked', resizeable: false, sortable: true],
[key:'roleDescription', label:'Role', resizeable: false, sortable: true]
]"
draggableColumns="true"
rowClickNavigation="true"
paginatorConfig="[
template:'{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {CurrentPageReport}',
pageReportTemplate:'{totalRecords} total record(s)',
alwaysVisible:true,
containers:'dt-paginator'
]"/>
<div id="dt-paginator" class="yui-skin-sam yui-pg-container"></div>
Changing the 'username' key to the following (sans quotes) does not help.
[key:'username', label:'Username', resizeable: false, sortable: true, sortOptions: { sortFunction: caseInsensitiveSortFunction }],
Both approaches create the following source. Note that the sortOptions for the username is blank.
<div id="dt_div_userTable"></div>
<script>
YAHOO.util.Event.onDOMReady(function () {
var DataSource = YAHOO.util.DataSource,
DataTable = YAHOO.widget.DataTable,
Paginator = YAHOO.widget.Paginator;
var userTable_ds = new DataSource('/admin/gpupUser/listJSON?');
userTable_ds.responseType = DataSource.TYPE_JSON;
userTable_ds.connMethodPost=true;
userTable_ds.responseSchema = {
resultsList : 'results',
fields : ["username","email","firstName","lastName","enabled","accountLocked","roleDescription","dataUrl"],
metaFields : {
totalRecords: 'totalRecords'
}
};
userTable_ds.doBeforeCallback = function(oRequest, oFullResponse, oParsedResponse, oCallback) {
return GRAILSUI.util.replaceDateStringsWithRealDates(oParsedResponse);
};
var userTable_paginator = new Paginator(
{'template': '{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {CurrentPageReport}',
'pageReportTemplate': '{totalRecords} total record(s)',
'alwaysVisible': true,
'containers': 'dt-paginator',
'rowsPerPage': 20}
);
var registerEditorListener = function(editor, field, url,successCallback,failureCallback) {
editor.subscribe("saveEvent", function(oArgs) {
GRAILSUI.userTable.loadingDialog.show();
var editorCallback = {
success: successCallback,
failure: function(o) {
// revert the cell value
GRAILSUI.userTable.updateCell(oArgs.editor.getRecord(), field, oArgs.oldData);
// alert user
if (failureCallback)
failureCallback(o);
else
alert('Received an error during edit: ' + o.responseText);
}
};
YAHOO.util.Connect.asyncRequest('POST', url, editorCallback, 'id=' + oArgs.editor.getRecord().getData('id') + '&field=' + field + '&newValue=' + oArgs.newData);
});
};
var myColumnDefs = [{'key': 'username',
'label': 'Username',
'resizeable': false,
'sortable': true,
'sortOptions': }, {'key': 'email',
'label': 'Email',
'resizeable': false,
'sortable': true}, {'key': 'firstName',
'label': 'First Name',
'resizeable': false,
'sortable': true}, {'key': 'lastName',
'label': 'Last Name',
'resizeable': false,
'sortable': true}, {'key': 'enabled',
'label': 'Enabled',
'resizeable': false,
'sortable': true}, {'key': 'accountLocked',
'label': 'Locked',
'resizeable': false,
'sortable': true}, {'key': 'roleDescription',
'label': 'Role',
'resizeable': false,
'sortable': true}, {'key': 'dataUrl',
'type': 'dataDrillDown',
'hidden': true}];
GRAILSUI.userTable = new GRAILSUI.DataTable('dt_div_userTable', myColumnDefs, userTable_ds, '', {
initialRequest : 'max=20&offset=0&sort=username&order=asc&',
paginator : userTable_paginator,
dynamicData : true,
sortedBy : {key: "username", dir: YAHOO.widget.DataTable.CLASS_ASC},
'draggableColumns': true,
'selectionMode': 'single',
'rowClickNavigate': false,
'rowClickMode': 'navigate',
'formatter': 'text'
});
// Update totalRecords on the fly with value from server
GRAILSUI.userTable.handleDataReturnPayload = function(oRequest, oResponse, oPayload) {
oPayload.totalRecords = oResponse.meta.totalRecords;
return oPayload;
};
// Set up editing flow
var highlightEditableCell = function(oArgs) {
var elCell = oArgs.target;
if(YAHOO.util.Dom.hasClass(elCell, "yui-dt-editable")) {
this.highlightCell(elCell);
}
};
GRAILSUI.userTable.subscribe("cellMouseoverEvent", highlightEditableCell);
GRAILSUI.userTable.subscribe("cellMouseoutEvent", GRAILSUI.userTable.onEventUnhighlightCell);
GRAILSUI.userTable.subscribe("cellClickEvent", GRAILSUI.userTable.onEventShowCellEditor);
});
</script>
<div id="dt-paginator" class="yui-skin-sam yui-pg-container"></div>
Is there any way to get the datatable to use a custom sortFunction when configured as a tag?
In listJSON action, add ignoreCase: true parameter to list(). See doc. It's probably the only easy way.
You cannot push a totally custom function from Javascript level to database level, if you're going to support paging - custom function will sort current page only, but paging will be based on default (by id) ordering. In other words, custom function works correctly for no more then 1-page tables.
You can customize sorting to certain extent if you use a Criteria or SQL in listJSON action - but still, you're limited to Hibernate or SQL level.
After digging into the code base, I finally realized that the sorting was being done on the server side, so I was able to address the issue there.

Resources