i am lost here. I probably not just yet made the understanding of darts idea of null safety and need your help.
i am extracting data from xml and am forming widgets out of it to have a app showing a forum website.
Certain XML element types i put into seperat classes, saving the inner values/data and creating a Container in the build-function, here you see my class for posts:
class Post extends StatelessWidget {
//const post({super.key});
dynamic userId;
dynamic date;
dynamic message;
XmlElement? avatar;
dynamic inThread;
dynamic inBoard;
dynamic tokenSetBookmark;
//Constructor: Used to fill variables with the values from the xml element given
Post(XmlElement xmlPost) {
userId = xmlPost.getElement("user");
date = xmlPost.getElement("date");
message = xmlPost.getElement("message");
avatar = xmlPost.getElement("avatar");
inThread = xmlPost.getElement("in-thread");
inBoard = xmlPost.getElement("in-thread");
tokenSetBookmark = xmlPost.getElement("token-setbookmark");
}
i tested this class in particular, it worked like a charm. Now i want to use this class in a different class but same idea: Have a class, use it for specific elements of the website to build widgets out of it. But whatever i do, i cannot get my nullable/not-nullable stuff together. First the class (shortened):
import './post.dart';
class Thread extends StatelessWidget {
//TODO
//const Thread({super.key});
dynamic id;
dynamic title;
dynamic subtitle;
dynamic numOfReplies;
dynamic numOfHits;
dynamic numOfPages;
dynamic flags = {
'is-closed': '0',
'is-sticky': '0',
'is-important': '0',
'is-announcement': '0',
'is-global': '0',
};
dynamic inBoard;
late Post firstPost;
late Post lastPost;
dynamic tokenNewReply;
List<Post> posts = [];
//Constructor: Used to fill variables with the values from the xml element given
Thread(XmlElement xmlThread, {super.key}) {
id = xmlThread.getAttribute("id");
title = xmlThread.getElement("title");
subtitle = xmlThread.getElement("subtitle");
numOfReplies = xmlThread.getElement("number-of-replies");
numOfHits = xmlThread.getElement("number-of-hits");
numOfPages = xmlThread.getElement("number-of-pages");
var parentElement = xmlThread.getElement("flags");
for (var element in parentElement!.childElements) {
switch (element.localName) {
case "is-closed":
flags["is-closed"] = element.getAttribute("value");
break;
case "is-sticky":
flags["is-sticky"] = element.getAttribute("value");
break;
case "is-important":
flags["is-important"] = element.getAttribute("value");
break;
case "is-announcement":
flags["is-announcement"] = element.getAttribute("value");
break;
case "is-global":
flags["is-global"] = element.getAttribute("value");
break;
default:
}
}
inBoard = xmlThread.getElement("in-board");
var tempElement = xmlThread.getElement("firstpost");
firstPost = Post(tempElement!.getElement("post"));
tempElement = xmlThread.getElement("lastpost");
lastPost = Post(tempElement?.getElement("post"));
}
The issue is on allocating firstpost and lastpost - the error reads The argument type 'XmlElement?' can't be assigned to the parameter type 'XMLElement'
the normal way how i handle it is to use ?. oder !. but both won't work - why?
CodePudding user response:
XmlElement.getElement
returns XmlElement?
which is nullable. So if you are sure that the value returned will not be null, then you can use. But it will thow an error if the value is null:
firstPost = Post(tempElement!.getElement("post")!);
lastPost = Post(tempElement!.getElement("post")!);
If it can be null, then you can check whether it is null then assign a value to the posts or you can define an empty constructor and assign it, when value is null.
firstPost = Post(tempElement?.getElement("post") ?? Post.empty());
lastPost = Post(tempElement!.getElement("post") ?? Post.empty());