Is there a way to add user defined data to a viewmodel at design time? - mdriven

What is the best way to add user defined data to a ViewModel at design time?
At runtime I want to display a subset of ViewModels for a class that don't require a root element. To do this at the moment I am tagging the ViewModels at design time by creating a ViewModel variable and assign it an intialvalue and using it as follows:
ViewModelUserControl vmc = new ViewModelUserControl();
vmc.ViewModelName = name;
vmc.SetEcoSpace(ecoSpace);
string vmTitle = vmc.ViewModel.ViewModelVariables
.Find(x =>x.Name=="vmUserTitle")?.InitialValue ?? "";
if (vmTitle != "")
{
...display and do stuff with the ViewModel...
Is there a better way?

ViewModels can have TaggedValues, on all levels. I would use that instead of a variable defintion.

Related

Returning variables from Model to other ViewControllers

I am making a weather application. I basically created a class where I will only get data from API and return them as needed. I have variables like cityName, currentWeather etc.
Problem is sometimes API doesn't provide them all so I need to check if they are nil or not before return them. What comes to my mind is set variables like this first:
private var cityNamePrivate: String!
and then
var cityNamePublic: String {
if cityNamePrivate == nil {
//
}
else { return cityNamePrivate }
But as you can as imagine, its very bad because I have a lots of variables. Is there any better logic for this? Should I just return them and check later in wherever I send them?
The problem here is that you will have many variables to deal with. It's not just returning them from the API, it's also dealing with them in your app and perhaps in some processing code.
One solution is to have a big class or struct with many properties. This will work very well, is straightforward to implement but will require lots of repetitive code. Moreover, it will require to change your API and all your code, whenever some new properties are made available by the remote web service.
Another approach is to have replace the big inflexible class or struct, with a dynamic container, e.g. an array of items [ Item ] or a dictionary that associates names to items [ String : Item ]. If the data is just strings, it's straightforward. If it's several types, you may have to have to implement a small type system for the elements. Example:
var x : [ String: String] = [:]
x["city"]="Strasbourg"
x["temperature"]="34°C"
struct Item {
var name : String
var value : String
}
var y : [ Item ] = [Item(name:"city",value:"Strasbourg"),
Item(name:"temperature", value:"34°C")]
The other advantage of this approach is that you stay loyal to the semantics: an information that is not available in the API (e.g. "unknown") is not the same as a default value. I.e. if the weather API does not return a temperature, you will not display 0 in your app. because 0 is not the same as "unknown". While strings are more robust in this matter, the absence of a name is not the same as an empty name.
This last remark suggests that in your current scheme, of having a big data transfer object, you should consider to keep the properties as optional, and move the responsibility for the processing of unknown data to your app.

Searching for a solution for more memory friendly way while adding elements to a list of class in flutter/dart

I'm trying to produce a runtime table. Below class and codes are simplified version of my final purpose.
class AppModel {
int appID;
String appName;
AppModel({this.appID, this.appName});
}
I'm calculating, fetching some another data and trying to fill the following object like this:
// _newApps value is between 1-30 mostly but not limited
List<AppModel> theList = [];
for (int i = 0; i < _newApps; i++) {
AppModel _newRecord = AppModel();
_newRecord.appID = _getNewAppID();
_newRecord.appName = _getNewAppName();
theList.add(_newRecord);
}
So the question is the code creates a new AppModel instance for only adding the element to the list for every iteration inside the for loop. According to my program logic, this event can be repeated 100-150 times sometimes.
Is it normal or is there any more memory efficient way to do so?
Thank you in advance.
I would like to point out (a better approach) that instead of for Loop you could have used the map method on the Apps List you have. And instead of creating a object every time in the Loop create a constructor for returning the object instance using the required details.
Hope you find it useful.

Hiding property setters by class in Swift

I would like to hide some property setters and initializers on my Swift model objects. These are reference data that the server provides, and under no circumstances should they be created or modified by the application. This is simple enough in Swift.
However, there is application in my project (a separate target) that needs to break this rule. It is a tool I use to populate the data in bulk, so of course needs to be able to initialize new model objects and set their properties.
What are my options for accomplishing this? I would rather not use a completely new project since it will mean a lot of code duplication. Is there some language-level way to keep this mutability hidden from one application but available to another?
If you declare a property with the let keyword. It can then only be set in the init of the type.
You can also declare a private setter to make the property readonly from the caller of the type but read/write inside the type
struct Foo {
private(set) var bar: Bool = true
func toggle() {
bar.toggle()
}
}
var foo = Foo()
let barState = foo.bar // This works
foo.toggle() // This works too
foo.bar.toggle() // This will make a compile time error

Separating classes

I have a class called UFDevice, in order to initialise it needs a location string.
I also have a class called UFResponse which among other things provides a location.
As the device only requires a location should I just take that in, so that it could be init'ed in some use case where there is no UFResponse.
Or should I pass in the whole response, in case later on it needs more info than just the location?
in pseudocode:
foundDevice(Data data) {
response = new UFResponse(data);
device = new UFDevice(response);
}
or:
foundDevice(Data data) {
response = new UFResponse(data);
device = new UFDevice(response.location);
}
or even should I encapsulate UFResponse in UFDevice, as currently it's only used to create UFDevices:
foundDevice(Data data) {
device = new UFDevice(data);
}
Future possibilities could include:
//maybe in the future I have saved a favourite location so need to do:
loadFavourite(String location) {
device = new UFDevice(location);
}
//or device needs more info
device = new UFDevice(location, color, ...20 more parameters...);
Where do I draw the line of separation? More importantly how can I decide this for myself in the future?
It sounds like a problem of interface segragation (https://en.wikipedia.org/wiki/Interface_segregation_principle). UFDevice is constructed from a UFResponse, but it doesn't need everything the UFResponse contains. It only needs a part of it, and you don't want UFDevice to be affected when UFResponse is changing in areas that should not affect UFDevice.
One approach is to have UFResponse inherit from an interface called UFDeviceParams, if this makes sense (might be multiple inheritance), and then UFDevice should get in its constructor a reference to UFDeviceParams.
This allows to initialize UFDevice based on the entire UFResponse, or based on a more light-weight instance of UFFavouriteParams (that also inherits from UFDeviceParams) that contains only the location + color etc...
foundDevice(Data data) {
response = new UFResponse(data);
device = new UFDevice(response);
}
loadFavourite(String location) {
params = new UFFavouriteParams(location);
device = new UFDevice(params);
}
To really know if this is the best approach for your case, one would need to learn more about your system, understand the use cases and the boundaries between modules. I recommend to watch Robert Martin's video on the Interface Segratation Principle and SOLID principles in general (https://cleancoders.com/category/solid-principles)

MVVM Property databinding

Why do most MVVM databinding properties examples check to see if the current value is equal to previous.
private string name;
public string Name
{
set
{
if(this.name != value) <- why is this check needed.
{...}
}
}
thanks!
In MVVM a property setter triggers the UI update following a property change. Adding this check prevents the UI to refresh (and possibly flicker) unnecessarily.
In the case of a Binding "TwoWay", When changing the value in the XAML, the value in the bound property in the ViewModel side must not re-send the same value. On the other hand if the value (ViewModel bind side) is not changed it is not necessary to throw the "RaiseChangedProperty" event to the View.