Reading JSON file into a QJsonDocument - qt

This is the structure of my json:
{
"images": [
{
"imagename": "banner.jpg",
"shapes": [
]
},
{
"imagename": "banner.png",
"shapes": [
]
},
{
"imagename": "logo.png",
"shapes": [
]
}
]
}
And this is the code I have:
QString filename = jsonFilePath;
QString val;
QFile file;
file.setFileName(filename);
file.open(QIODevice::ReadOnly | QIODevice::Text);
val = file.readAll();
file.close();
QJsonDocument d = QJsonDocument::fromJson(val.toUtf8());
qDebug() << d;
When I run the above code, and try and output d using qDebug() all that is printed to the console is QJsonDocument().

Your code works OK if there are no runtime errors. I'd suggest to check for runtime errors:
Check the return result of file.open().
Use a second argument of QJsonDocument::fromJson() to catch JSON parsing errors and print them like that:
QJsonParseError err;
QJsonDocument d = QJsonDocument::fromJson(val.toUtf8(), &err);
qDebug() << d << err.errorString();
Hope this helps to catch the error.

I would suggest using the toJson() method when printing a QJsonDocument
qDebug() << "Json Document:" << d.toJson();

Related

impement operator [] like in QVariantMap for QML

Main goal is make ContextProperty for QML like QVariantMap with access operator []:
For example cpp file:
...
QVariantMap qvm; qvm["zero"] = "it's OK";
view.rootContext()->setContextProperty("qvm",qvm);
...
qml file:
console.log("qvm[zero] === "+qvm["zero"]); // output: qvm[zero] === it's OK
but with my class:
class MyStore : public QObject
{
Q_OBJECT
public:
MyStore(QObject* parent=nullptr):QObject(parent){
}
MyStore(const MyStore &other,QObject* parent=nullptr):QObject(parent){ store = other.store; }
~MyStore(){}
inline const QVariant &operator[](QString i) const {
static const QVariant val(store[i]);
return val;
}
QVariantMap store;
};
Q_DECLARE_METATYPE(MyStore);
cpp file:
store.store["zero"] = "OK only in cpp";
qDebug("main: store[\"zero\"] == %s", store["zero"].toString().toAscii().data()); // output: main: store["zero"] == "OK only in cpp"
view.rootContext()->setContextProperty("mystore",&store);
qml file:
console.log("qml: mystore[\"zero\"] === "+mystore["zero"]); // output: qml: mystore["zero"] === undefined
How to implement for output:
qml: mystore["zero"] === "OK only in cpp"
?

DynamoDB table seed works in cli but not AWS-SDK

I have a table that has more than 25 items and wrote a basic script to break them into sub arrays of 25 items each then loops thru that collection of sub arrays to run a batch write item command in the AWS DynamoDB Client. The issue I am getting is a returned validation error. When I run the same seed file via the aws-cli it seeds the table perfectly. This makes me think it has something to do with my script. See anything I am missing? Thanks in advance!
var { DynamoDB } = require('aws-sdk');
var db = new DynamoDB.DocumentClient({
region: 'localhost',
endpoint: 'http://localhost:8000',
});
const allItems = require('./allItems.json');
const tableName = 'some-table-name';
console.log({ tableName, allItems });
var batches = [];
var currentBatch = [];
var count = 0;
for (let i = 0; i < allItems.length; i++) {
//push item to the current batch
count++;
currentBatch.push(allItems[i]);
if (count === 25) {
batches.push(currentBatch);
currentBatch = [];
}
}
//if there are still items left in the curr batch, add to the collection of batches
if (currentBatch.length > 0 && currentBatch.length !== 25) {
batches.push(currentBatch);
}
var completedRequests = 0;
var errors = false;
//request handler for DynamoDB
function requestHandler(err, data) {
console.log('In the request handler...');
return function (err, data) {
completedRequests++;
errors = errors ? true : err;
//log error
if (errors) {
console.error('Request caused a DB error.');
console.error('ERROR: ' + err);
console.error(JSON.stringify(err, null, 2));
} else {
var res = {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': true,
},
body: JSON.stringify(data),
isBase64Encoded: false,
};
console.log(`Success: returned ${data}`);
return res;
}
if (completedRequests == batches.length) {
return errors;
}
};
}
//Make request
var params;
for (let j = 0; j < batches.length; j++) {
//items go in params.RequestedItems.id array
//format for the items is {PutRequest : {Item: ITEM_OBJECT}}
params = '{"RequestItems": {"' + tableName + '": []}}';
params = JSON.parse(params);
params.RequestItems[tableName] = batches[j];
console.log('before db.batchWriteItem: ', params);
try {
//send to db
db.batchWrite(params, requestHandler(params));
} catch{
console.error(err)
}
}
Here is the formatted request object and the error:
before db.batchWriteItem:
{ RequestItems:
{ 'some-table-name': [ [Object], [Object], [Object], [Object] ] }
}
In the request handler...
Request caused a DB error.
ERROR: ValidationException: Invalid attribute value type
{
"message": "Invalid attribute value type",
"code": "ValidationException",
"time": "2020-08-04T10:51:13.751Z",
"requestId": "dd49628c-6ee9-4275-9349-6edca29636fd",
"statusCode": 400,
"retryable": false,
"retryDelay": 47.94198279972915
}
You are using the DocumentClient in the nodejs code. This will automatically convert the data format used by DynamoDB to a more easily consumable format.
e.g.
{
"id": {
"S": "A string value"
}
}
would become
{
"id": "A string value"
}
The CLI does not perform this data conversion.
You can use the regular DynamoDB client to not perform this conversion in Nodejs. e.g. const db = new Dynamodb()

Rename a stream of JSON entities

I have a stream of JSON entities. Here is one of them called 'info':
null
null
{
"id": "qwefhu214o",
"number": "2346",
"date": "28.01.2019"
}
null
null
{
"id": "esg324lif",
"number": "1378",
"date": "29.05.2019"
}
{
"id": "gwrs853sdf",
"number": "4487",
"date": "20.12.2019"
}
I want to extract keys from nested json, so it looks like this:
null
null
{
"info_id": "qwefhu214o",
"info_number": "2346",
"info_date": "28.01.2019"
}
null
null
{
"info_id": "esg324lif",
"info_number": "1378",
"info_date": "29.05.2019"
}
{
"info_id": "gwrs853sdf",
"info_number": "4487",
"info_date": "20.12.2019"
}
I try this, but it doesn't work:
jqr::jq('.[].info |= with_entries(.key |= "info_" + .)')
Its says:
Error: lexical error: invalid char in json text.
NA
(right here) ------^
I guess it because of NULLs. How could i do that? Should i put somewhere "?" in code ? That code works for cases when there are np NULLs
The "nested JSON" shown is actually a stream of JSON entities,
for which the following filter will produce the desired results:
if . then with_entries(.key |= "info_" + .) else . end
You can easily modify this filter as required.

Qt style plugin loaded but key is missing

I was trying to create a style plugin for my project, the plugin seems being loaded, but why QStyleFactory::keys() didn't return my key?
By setting QT_DEBUG_PLUGINS to 1, I got following message :
Found metadata in lib .../styles/libstyles.so, metadata=
{
"IID": "this.is.my.style",
"MetaData": {
"Keys": [
"mystyle"
]
},
"className": "MyStylePlugin",
"debug": true,
"version": 329986
}
in my main():
QApplication app(argc, argv);
QApplication::setStyle(QStyleFactory::create("mystyle"));
qDebug() << QStyleFactory::keys();
The last qDebug statement prints:
Got keys from plugin meta data ()
("Windows", "Fusion") <= Shouldn't "mystyle" also show up here?
That's because your IID should be ""org.qt-project.Qt.QStyleFactoryInterface" not "this.is.my.style". If you change the IID, the plugin is not recognize as a style plugin by Qt.
Here is an extract of Qt code where the keys are detected:
QString iid = library->metaData.value(QLatin1String("IID")).toString();
if (iid == QLatin1String(d->iid.constData(), d->iid.size())) {
QJsonObject object = library->metaData.value(QLatin1String("MetaData")).toObject();
metaDataOk = true;
QJsonArray k = object.value(QLatin1String("Keys")).toArray();
for (int i = 0; i < k.size(); ++i)
keys += d->cs ? k.at(i).toString() : k.at(i).toString().toLower();
}
if (qt_debug_component())
qDebug() << "Got keys from plugin meta data" << keys;
You can see that on the 2nd line if the IID from you plugin does not match the expected IID (d->iid), the code will not bother to try to read the MetaData.

C# ASP.NET json objects to array

I am stuck on this error. This is my JSON data:
{
"date": "2016-08-26",
"time_of_day": "14:19",
"request_time": "2016-08-26T14:19:59+01:00",
"station_name": "Derby",
"station_code": "DBY",
"departures": {
"all": [
{
"mode": "train",
"service": "22152000",
"train_uid": "C65080"
},
{
"mode": "train",
"service": "22150000",
"train_uid": "C65145"
},
{
"mode": "train",
"service": "22180008",
"train_uid": "C70700"
}
]
}
}
What I am trying to do is add the service json object to an array, after this I want to increment through the service list and add each service to a separate API call. This is my code:
dynamic content = JsonConvert.DeserializeObject(json);
dynamic departures = content.departures;
dynamic DepartTimes = departures.all;
JArray items = ((JArray)DepartTimes["service"]);
int serviceLength = items.Count;
for (int i = 0; i < serviceLength; i++)
{
//next api call containing array increment
}
The error seems to be here :
JArray items = ((JArray)DepartTimes["service"]);
Any help is much appreciated, thank you!
One possible way is -
var json = "json";
dynamic d = JsonConvert.DeserializeObject(json);
JArray arr = new JArray();
foreach(JObject o in d.departures.all){
arr.Add(o["service"]);
}
Console.Write(arr.Count); //output : 3
Provided Json data is not proper. Second and third items must have open curly braces ({)
In addition, an example working code may be:
dynamic content = JsonConvert.DeserializeObject(json));
JArray items = (JArray)content.departures.all;
var newArray = items.Select(x=>x["service"].ToString()).ToArray();

Resources