Decoding optional values in JSON - Swift 4 - swift

I've read read many tutorials and searched for answers here on SO;
Decoding Nested JSON with Optional Values Swift 4
Swift 4 Not decoding JSON optional properly
Decoding optionals doesn't seem problematic using below code. Obviously I'm doing something wrong, but what is it!?
Part of my code:
struct ProductInfo: Codable {
var name: String?
let images: [Image]
var ingredients: String?
let origin: [Origin]
let producer: Producer
enum CodingKeys: String, CodingKey {
case name = "Artikelbenamning"
case images = "Bilder"
case ingredients = "Ingrediensforteckning"
case origin = "Tillverkningslander"
case producer = "Varumarke"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try? values.decodeIfPresent(String.self, forKey: .name)!
images = try values.decodeIfPresent([Image].self, forKey: .images)!
ingredients = try? values.decodeIfPresent(String.self, forKey: .ingredients)!
origin = try values.decodeIfPresent([Origin].self, forKey: .origin)!
producer = try values.decodeIfPresent(Producer.self, forKey: .producer)!
}
}
The app queries a products database. Following json is returned when a product doesn't exist. App crashes when trying to decode nil name ("Artikelbenamning in json) in init(from:).
{
"GTIN": null,
"TillverkarensArtikelnummer": null,
"Artikelbenamning": null,
"RegleratProduktnamn": null,
"Forvaringsinstruktion": null,
"Variabelmattsindikator": false,
"Bruttovikt": null,
"Bredd": null,
"Djup": null,
"Hojd": null,
"Returemballage": false,
"FarligtGodsKod": null,
"FarligtGodsKlass": null,
"FarligtGodsForpackningsgrupp": null,
"GPCKod": null,
"GiltigFROM": null,
"Publiceringsdatum": null,
"FakturerbarEnhet": false,
"Slutdatum": null,
"GiltighetsdatumPris": null,
"Tillganglighetstidpunkt": null,
"SistaTillganglighetstidpunkt": null,
"SkapadDatum": null,
"SenastAndradDatum": null,
"Flampunkt": null,
"KodBegransadMangd": null,
"OfficiellTransportbenamning": null,
"OspecificeradTransportbenamning": null,
"TunnelrestriktionADR": null,
"KlassificeringskodFarligtgods": null,
"Transportkategori": null,
"Konsumentartikel": false,
"BestallningsbarForpackning": false,
"RabattOlaglig": null,
"Garantiloptid": 0,
"Konsumentdatum": null,
"Tjanst": false,
"Sasongsindikator": null,
"Engangskop": null,
"AntalReturnerbaraEnheter": 0,
"Staplingsriktning": null,
"Staplingstyp": null,
"MaxTransportTemperatur": 0.0,
"MinTransportTemperatur": 0.0,
"Anvandningsinstruktioner": null,
"HallbarhetEfterOppning": 0,
"Riskfras": null,
"KodlistutgivareRiskfras": null,
"Klassificeringssystem": null,
"FarligtGodsBegransadMangd": null,
"FarligtGodsOvrigInfo": null,
"FarligtGodsSarbestammelser": null,
"T3495_Artikelavisering": null,
"T4032_TypAvUtgangsdatum": null,
"T3742_ForstaLeveransdatum": null,
"Undervarumarke": null,
"Niva": null,
"Produktbladslank": null,
"KompletterandeProduktklass": null,
"T4200_AllmänPubliceringstidpunkt": null,
"T3848_TypAvTryckkanslighet": null,
"Varningsetiketter": [],
"Sasongskoder": [],
"Produktklasser": [],
"MaskinellMarkningar": [],
"Bilder": [],
"ReferenserTillAndraArtiklar": [],
"MSRKritierier": [],
"Kravspecifikationer": [],
"Receptlinks": [],
"Allergener": [],
"Markningar": [],
"Ingredienser": [],
"Tillagningsinformation": [],
"Tillverkningslander": [],
"Naringsinfo": [],
"Serveringsforslag": [],
"Diettyper": [],
"Tillagningsmetoder": [],
"Farger": [],
"VillkorForsaljning": [],
"Varumarke": {
"Varumarke": null,
"AgareGLN": null,
"AgareNamn": null,
"Tillverkare": {
"Namn": null,
"EAN": null
}
},
"Nettoinnehall": [],
"Kontakter": [],
"Faroangivelser": [],
"Sakerhet": [],
"Forpackningar": [],
"Tillsatser": [],
"Substanser": [],
"Fangstzoner": [],
"Marknadsbudskap": null,
"KortMarknadsbudskap": null,
"Komponenter": null
}

The API decodeIfPresent is pointless in this case because the key does exist.
An existing key with null value and a missing key are two different situations.
And never force unwrap in the init(from decoder method.
There are two options:
Delete the entire init method then the optional struct members handle the null values.
Use regular decode and ignore the error
name = try? values.decode(String.self, forKey: .name)

Related

entity framework output parameter from store procedure.it adds the record fine but i need id of newly inserted record back

here is my code
System.Data.Entity.Core.Objects.ObjectParameter output = new System.Data.Entity.Core.Objects.ObjectParameter("userID", typeof(int));
db.Proc_UserAccounts_AddNew(output, obj.Name, obj.Password, obj.SignUpDate, obj.Inactive, obj.Address, obj.Phone,
obj.Email, obj.VerificationCode, obj.Cell, obj.Fax, countryid, null, 10, obj.ServiceDescription, "", "", "", "", "", "1", null,
null, null, null, null, null, null, null, null);

Rescale google line chart X axis when a series is hidden

I am hiding/showing series in a google line chart when the legend is clicked using this code:
var columns = [];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
if (i > 0) {
series[i - 1] = {};
}
}
google.visualization.events.addListener(chart, 'select', function () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (sel[0].row === null) {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function () {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
}
else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, burndown_options);
}
}
});
When a series is hidden the Y axis automatically rescales itself. Is there a way to also get the X axis to rescale?
Here is a jsfiddle with my code and data: http://jsfiddle.net/LarryMartell/my906Lw2/5/
although the columns may be excluded in the view by returning null,
all of the rows are still present,
which is why the x-axis doesn't change.
we must exclude the rows where all values are null,
in order to re-scale the x-axis.
// exclude rows where all columns = null
var rows = [];
var validRow;
for (var r = 0; r < view.getNumberOfRows(); r++) {
validRow = null;
for (var c = 1; c < view.getNumberOfColumns(); c++) {
validRow = validRow || view.getValue(r, c);
}
if (validRow !== null) {
rows.push(r);
}
}
view.setRows(rows);
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Day');
data.addColumn('number', 'S1');
data.addColumn('number', 'S2');
data.addColumn('number', 'S3');
data.addColumn('number', 'S4');
data.addColumn('number', 'S5');
data.addColumn('number', 'S6');
var rows = [
["Nov 2019", null, null, 92617.19, null, 92617.19, null],
["Dec 2019", null, null, 92617.19, null, 92617.19, null],
["Jan 2020", 3251.84, 16259.2, 92617.19, 2002.02, 94619.2, null],
["Feb 2020", 3251.84, 16259.2, 92617.19, 4004.03, 96621.22, null],
["Mar 2020", 6503.68, 32518.4, 92617.19, 8008.06, 100625.25, null],
["Apr 2020", 6503.68, 32518.4, 92617.19, 12012.1, 104629.28, null],
["May 2020", 6503.68, 32518.4, 83355.47, 16016.13, 99371.59, null],
["Jun 2020", 13007.36, 65036.81, 74093.75, 24024.19, 98117.94, null],
["Jul 2020", 13007.36, 65036.81, 64832.03, 32032.26, 96864.29, null],
["Aug 2020", 13007.36, 65036.81, 55570.31, 40040.32, 95610.63, null],
["Sep 2020", 13007.36, 65036.81, 46308.59, 48048.38, 94356.98, null],
["Oct 2020", 13007.36, 65036.81, 37046.87, 56056.45, 93103.32, null],
["Nov 2020", 13007.36, 65036.81, 18523.44, 64064.51, 82587.95, null],
["Dec 2020", 13007.36, 65036.81, 13892.58, 72072.58, 85965.15, null],
["Jan 2021", 13007.36, 65036.81, 11114.06, 80080.64, 91194.7, null],
["Feb 2021", null, null, null, 80080.64, null, 650368.08],
["Mar 2021", null, null, null, 80080.64, null, 637831.53],
["Apr 2021", null, null, null, 80080.64, null, 625294.99],
["May 2021", null, null, null, 80080.64, null, 612758.44],
["Jun 2021", null, null, null, 80080.64, null, 600221.89],
["Jul 2021", null, null, null, 80080.64, null, 587685.35],
["Aug 2021", null, null, null, 80080.64, null, 575148.8],
["Sep 2021", null, null, null, 80080.64, null, 562612.26],
["Oct 2021", null, null, null, 80080.64, null, 550075.71],
["Nov 2021", null, null, null, 80080.64, null, 537539.16],
["Dec 2021", null, null, null, 80080.64, null, 525002.62],
["Jan 2022", null, null, null, 80080.64, null, 512466.07],
["Feb 2022", null, null, null, 80080.64, null, 499929.52],
["Mar 2022", null, null, null, 80080.64, null, 487392.98],
["Apr 2022", null, null, null, 80080.64, null, 474856.43],
["May 2022", null, null, null, 80080.64, null, 462319.89],
["Jun 2022", null, null, null, 80080.64, null, 449783.34],
["Jul 2022", null, null, null, 80080.64, null, 437246.79],
["Aug 2022", null, null, null, 80080.64, null, 424710.25],
["Sep 2022", null, null, null, 80080.64, null, 412173.7],
["Oct 2022", null, null, null, 80080.64, null, 399637.15],
["Nov 2022", null, null, null, 80080.64, null, 387100.61],
["Dec 2022", null, null, null, 80080.64, null, 374564.06],
["Jan 2023", null, null, null, 80080.64, null, 362027.52],
["Feb 2023", null, null, null, 80080.64, null, 349490.97],
["Mar 2023", null, null, null, 80080.64, null, 336954.42],
["Apr 2023", null, null, null, 80080.64, null, 324417.88],
["May 2023", null, null, null, 80080.64, null, 311881.33],
["Jun 2023", null, null, null, 80080.64, null, 299344.78],
["Jul 2023", null, null, null, 80080.64, null, 286808.24],
["Aug 2023", null, null, null, 80080.64, null, 274271.69],
["Sep 2023", null, null, null, 80080.64, null, 261735.14],
["Oct 2023", null, null, null, 80080.64, null, 249198.6],
["Nov 2023", null, null, null, 80080.64, null, 236662.05],
["Dec 2023", null, null, null, 80080.64, null, 224125.51],
["Jan 2024", null, null, null, 80080.64, null, 211588.96],
["Feb 2024", null, null, null, 80080.64, null, 199052.41]
];
data.addRows(rows);
options = {
hAxis: {
title: '',
slantedText: true,
slantedTextAngle: 90
},
vAxis: {
title: '',
format: '$#,###'
},
title: "",
width: 800,
height: 500,
isStacked: "true",
pointSize: 5,
legend: {
position: 'bottom'
},
interpolateNulls: true,
vAxis: {
format: 'currency'
}
};
chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
var columns = [];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
if (i > 0) {
series[i - 1] = {};
}
}
options['series'] = series;
google.visualization.events.addListener(chart, 'select', function() {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (sel[0].row === null) {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function() {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
} else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
// exclude rows where all columns = null
var rows = [];
var validRow;
for (var r = 0; r < view.getNumberOfRows(); r++) {
validRow = null;
for (var c = 1; c < view.getNumberOfColumns(); c++) {
validRow = validRow || view.getValue(r, c);
}
if (validRow !== null) {
rows.push(r);
}
}
view.setRows(rows);
chart.draw(view, options);
}
}
});
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
NOTE: the jsfiddle is using an old version of google charts.
the jsapi loader is out of date and should no longer be used.
instead, use loader.js, this will only change the load statement.
see above snippet...

updating elements in nested arrays

I think I know how to get to my object, I just can't figure out how to update it's values. I am getting this error:
{
"name": "MongoError",
"message": "cannot use the part (tasks of families.25.tasks.name) to traverse the element ({tasks: [ { name: \"Correct Name\", isSelected: false, completedBy: null, submittedBy: \"web-user\", completedOn: null, submittedOn: new Date(1505857352113), message: \"Please correct family name to follow HOK standard.\", assignedTo: \"konrad.sobon\", _id: ObjectId('59c18f8991d1929d43f22f8c') }, { name: \"Some other task\", isSelected: false, completedBy: null, submittedBy: \"web-user\", completedOn: null, submittedOn: new Date(1505917405948), message: \"Yet again, testing this.\", assignedTo: \"konrad.sobon\", _id: ObjectId('59c279fb8388cb58e7454bf6') } ]})",
"driver": true,
"index": 0,
"code": 16837,
"errmsg": "cannot use the part (tasks of families.25.tasks.name) to traverse the element ({tasks: [ { name: \"Correct Name\", isSelected: false, completedBy: null, submittedBy: \"web-user\", completedOn: null, submittedOn: new Date(1505857352113), message: \"Please correct family name to follow HOK standard.\", assignedTo: \"konrad.sobon\", _id: ObjectId('59c18f8991d1929d43f22f8c') }, { name: \"Some other task\", isSelected: false, completedBy: null, submittedBy: \"web-user\", completedOn: null, submittedOn: new Date(1505917405948), message: \"Yet again, testing this.\", assignedTo: \"konrad.sobon\", _id: ObjectId('59c279fb8388cb58e7454bf6') } ]})"
}
My collection looks like this:
My request handler looks like this:
module.exports.updateTask = function (req, res) {
var id = req.params.id;
var taskId = mongoose.Types.ObjectId(req.params.taskid);
Families
.update(
{ _id: id, 'families.tasks._id': taskId},
{ $set: {
'families.$.tasks.name': req.body.name,
'families.$.tasks.message': req.body.message,
'families.$.tasks.assignedTo': req.body.assignedTo}}, function(err, result){
if(err) {
res
.status(400)
.json(err);
} else {
res
.status(202)
.json(result);
}
}
)
};
Any help will be appreciated.
Unfortunately the positional operator $ cannot be used for nested arrays:
The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value.
https://docs.mongodb.com/manual/reference/operator/update/positional/
You might have to consider restructuring your documents.

How to save my datas in jTable

I did my frame by using jFrame.There is a jTable on it with 6 columns and 15 rows.I want to save my table on file or text.And I want to get them in same columns and same rows when i click on load.How can i do that ?
thanks in advance.
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null, null, null, null, null, null},
{null, null, null, null, null, null, null},
{null, null, null, null, null, null, null},
{null, null, null, null, null, null, null},},
new String [] {
"İSİM", "NO", "İZİN NEDENİ", "İZİNE ÇIKIŞ TARİHİ", "İZİN GÜNÜ", "İZİN BİTİŞ TARİHİ", "KALAN izin hakkı"
}
));

inserting arrays strange behavior or bug ? in mongo

db.foo.remove();
var a10001 = Array(90,0,5,134);
var a10002 = Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,107);
var a10003 = Array(202);
db.foo.insert({
a10001 : a10001,
a10002 : a10002,
a10003 : a10003
});
first two arrays a10001 a10002 are the same as inserted the third a10003 is not !
db.foo.find( {} , { "a10003" : 1} );
{ "_id" : ObjectId("534e031ad1844c26ea167205"), "a10003" : [ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null ] }
but when I add one element to third array
var a10003 = Array(202,1);
it behaves well.
{ "_id" : ObjectId("534e0402d1844c26ea167206"), "a10003" : [ 202, 1 ] }
Version:
mongod --version
db version v2.4.9
Wed Apr 16 06:02:33.649 git version: 52fe0d21959e32a5bdbecdc62057db386e4e029c
i think your syntax is not correct , As you can see here Create a JavaScript array containing 1...N. It means Array(202) create empty array with 202 as size.
var foo = new Array(202);//create a 202 element array
You can try like this
var foo = new Array();
foo.push(202);
#Devesh is right.
When you are trying to create an Array Object with single parameter x which is an integer(if it is a not an integer then it will create a array with that element, you can try with boolean or string) then it means that you are initializing an array of some length with undefined values.
And if you will use that array when inserting into a mongoDB collection then mongoDB will insert null values. See the commands I ran in mongo shell.
> var arr = new Array(1);
> arr
[ undefined ]
> arr.length
1
> var arr = new Array(5)
> arr.length
5
> arr
[ undefined, undefined, undefined, undefined, undefined ]
> var arr = new Array(5,3,4)
> arr.length
3
> arr
[ 5, 3, 4 ]
> var arr = new Array(5)
> arr
[ undefined, undefined, undefined, undefined, undefined ]
> db.testing.insert({arr:arr})
WriteResult({ "nInserted" : 1 })
> db.testing.find().pretty();
{
"_id" : ObjectId("534e0f9fbdb7d435d4bc46d5"),
"arr" : [
null,
null,
null,
null,
null
]
}
> var arr = new Array(5,4,3,2,1)
> db.testing.insert({arr:arr})
WriteResult({ "nInserted" : 1 })
> db.testing.find().pretty();
{
"_id" : ObjectId("534e0f9fbdb7d435d4bc46d5"),
"arr" : [
null,
null,
null,
null,
null
]
}
{
"_id" : ObjectId("534e10c8bdb7d435d4bc46d6"),
"arr" : [
5,
4,
3,
2,
1
]
}
I hope it helps.
Other links from where you can take reference from
http://docs.mongodb.org/manual/reference/operator/update-array/
http://docs.mongodb.org/manual/reference/method/db.collection.insert/