Is there a Language supported way to make a full (deep) copy of an Object in Dart?
If multiple options exist, what are their differences?
Darts built-in collections use a named constructor called "from" to accomplish this. See this post: Clone a List, Map or Set in Dart
Map mapA = {
'foo': 'bar'
};
Map mapB = new Map.from(mapA);
No as far as open issues seems to suggest:
https://github.com/dart-lang/sdk/issues/3367
And specifically:
... Objects have identity, and you can only pass around references to them. There is no implicit copying.
Late to the party, but I recently faced this problem and had to do something along the lines of :-
class RandomObject {
RandomObject(this.x, this.y);
RandomObject.clone(RandomObject randomObject): this(randomObject.x, randomObject.y);
int x;
int y;
}
Then, you can just call copy with the original, like so:
final RandomObject original = RandomObject(1, 2);
final RandomObject copy = RandomObject.clone(original);
I guess for not-too-complex objects, you could use the convert library:
import 'dart:convert';
and then use the JSON encode/decode functionality
Map clonedObject = JSON.decode(JSON.encode(object));
If you're using a custom class as a value in the object to clone, the class either needs to implement a toJson() method or you have to provide a toEncodable function for the JSON.encode method and a reviver method for the decode call.
Unfortunately no language support. What I did is to create an abstract class called Copyable which I can implement in the classes I want to be able to copy:
abstract class Copyable<T> {
T copy();
T copyWith();
}
I can then use this as follows, e.g. for a Location object:
class Location implements Copyable<Location> {
Location({
required this.longitude,
required this.latitude,
required this.timestamp,
});
final double longitude;
final double latitude;
final DateTime timestamp;
#override
Location copy() => Location(
longitude: longitude,
latitude: latitude,
timestamp: timestamp,
);
#override
Location copyWith({
double? longitude,
double? latitude,
DateTime? timestamp,
}) =>
Location(
longitude: longitude ?? this.longitude,
latitude: latitude ?? this.latitude,
timestamp: timestamp ?? this.timestamp,
);
}
To copy an object without reference, the solution I found was similar to the one posted here, however if the object contains MAP or LIST you have to do it this way:
class Item {
int id;
String nome;
String email;
bool logado;
Map mapa;
List lista;
Item({this.id, this.nome, this.email, this.logado, this.mapa, this.lista});
Item copyWith({ int id, String nome, String email, bool logado, Map mapa, List lista }) {
return Item(
id: id ?? this.id,
nome: nome ?? this.nome,
email: email ?? this.email,
logado: logado ?? this.logado,
mapa: mapa ?? Map.from(this.mapa ?? {}),
lista: lista ?? List.from(this.lista ?? []),
);
}
}
Item item1 = Item(
id: 1,
nome: 'João Silva',
email: 'joaosilva#gmail.com',
logado: true,
mapa: {
'chave1': 'valor1',
'chave2': 'valor2',
},
lista: ['1', '2'],
);
// -----------------
// copy and change data
Item item2 = item1.copyWith(
id: 2,
nome: 'Pedro de Nobrega',
lista: ['4', '5', '6', '7', '8']
);
// -----------------
// copy and not change data
Item item3 = item1.copyWith();
// -----------------
// copy and change a specific key of Map or List
Item item4 = item1.copyWith();
item4.mapa['chave2'] = 'valor2New';
See an example on dartpad
https://dartpad.dev/f114ef18700a41a3aa04a4837c13c70e
With reference to #Phill Wiggins's answer, here is an example with .from constructor and named parameters:
class SomeObject{
String parameter1;
String parameter2;
// Normal Constructor
SomeObject({
this.parameter1,
this.parameter2,
});
// .from Constructor for copying
factory SomeObject.from(SomeObject objectA){
return SomeObject(
parameter1: objectA.parameter1,
parameter2: objectA.parameter2,
);
}
}
Then, do this where you want to copy:
SomeObject a = SomeObject(parameter1: "param1", parameter2: "param2");
SomeObject copyOfA = SomeObject.from(a);
Let's say you a have class
Class DailyInfo
{
String xxx;
}
Make a new clone of the class object dailyInfo by
DailyInfo newDailyInfo = new DailyInfo.fromJson(dailyInfo.toJson());
For this to work your class must have implemented
factory DailyInfo.fromJson(Map<String, dynamic> json) => _$DailyInfoFromJson(json);
Map<String, dynamic> toJson() => _$DailyInfoToJson(this);
which can be done by making class serializable using
#JsonSerializable(fieldRename: FieldRename.snake, includeIfNull: false)
Class DailyInfo{
String xxx;
}
It only works for object types that can be represented by JSON.
ClassName newObj = ClassName.fromMap(obj.toMap());
or
ClassName newObj = ClassName.fromJson(obj.toJson());
Trying using a Copyable interface provided by Dart.
there is an easier way for this issue
just use ... operator
for example, clone a Map
Map p = {'name' : 'parsa','age' : 27};
Map n = {...p};
also, you can do this for class properties.
in my case, I was needed to clone a listed property of a class.
So:
class P1 {
List<String> names = [some data];
}
/// codes
P1 p = P1();
List<String> clonedList = [...p.names]
// now clonedList is an unreferenced type
There is no built-in way of deep cloning an object - you have to provide the method for it yourself.
I often have a need to encode/decode my classes from JSON, so I usually provide MyClass fromMap(Map) and Map<String, dynamic> toJson() methods. These can be used to create a deep clone by first encoding the object to JSON and then decoding it back.
However, for performance reasons, I usually implement a separate clone method instead. It's a few minutes work, but I find that it is often time well spent.
In the example below, cloneSlow uses the JSON-technique, and cloneFast uses the explicitly implemented clone method. The printouts prove that the clone is really a deep clone, and not just a copy of the reference to a.
import 'dart:convert';
class A{
String a;
A(this.a);
factory A.fromMap(Map map){
return A(
map['a']
);
}
Map<String, dynamic> toJson(){
return {
'a': a
};
}
A cloneSlow(){
return A.fromMap(jsonDecode(jsonEncode(this)));
}
A cloneFast(){
return A(
a
);
}
#override
String toString() => 'A(a: $a)';
}
void main() {
A a = A('a');
A b = a.cloneFast();
b.a = 'b';
print('a: $a b: $b');
}
There's no API for cloning/deep-copying built into Dart.
We have to write clone() methods ourselves & (for better or worse) the Dart authors want it that way.
Deep copy Object /w List
If the Object we're cloning has a List of Objects as a field, we need to List.generate that field and those Objects need their own clone method.
Example of cloning method (copyWith()) on an Order class with a List field of objects (and those nested objects also have a copyWith()):
Order copyWith({
int? id,
Customer? customer,
List<OrderItem>? items,
}) {
return Order(
id: id ?? this.id,
customer: customer ?? this.customer,
//items: items ?? this.items, // this will NOT work, it references
items: items ?? List.generate(this.items.length, (i) => this.items[i].copyWith()),
);
}
Gunter mentions this here.
Note, we cannot use List.from(items) nor [...items]. These both only make shallow copies.
Dart does not share Memory within multiple threads (isolate), so...
extension Clone<T> on T {
/// in Flutter
Future<T> clone() => compute<T, T>((e) => e, this);
/// in Dart
Future<T> clone() async {
final receive = ReceivePort();
receive.sendPort.send(this);
return receive.first.then((e) => e as T).whenComplete(receive.close);
}
}
An example of Deep copy in dart.
void main() {
Person person1 = Person(
id: 1001,
firstName: 'John',
lastName: 'Doe',
email: 'john.doe#email.com',
alive: true);
Person person2 = Person(
id: person1.id,
firstName: person1.firstName,
lastName: person1.lastName,
email: person1.email,
alive: person1.alive);
print('Object: person1');
print('id : ${person1.id}');
print('fName : ${person1.firstName}');
print('lName : ${person1.lastName}');
print('email : ${person1.email}');
print('alive : ${person1.alive}');
print('=hashCode=: ${person1.hashCode}');
print('Object: person2');
print('id : ${person2.id}');
print('fName : ${person2.firstName}');
print('lName : ${person2.lastName}');
print('email : ${person2.email}');
print('alive : ${person2.alive}');
print('=hashCode=: ${person2.hashCode}');
}
class Person {
int id;
String firstName;
String lastName;
String email;
bool alive;
Person({this.id, this.firstName, this.lastName, this.email, this.alive});
}
And the output below.
id : 1001
fName : John
lName : Doe
email : john.doe#email.com
alive : true
=hashCode=: 515186678
Object: person2
id : 1001
fName : John
lName : Doe
email : john.doe#email.com
alive : true
=hashCode=: 686393765
// Hope this work
void main() {
List newList = [{"top": 179.399, "left": 384.5, "bottom": 362.6, "right": 1534.5}, {"top": 384.4, "left": 656.5, "bottom": 574.6, "right": 1264.5}];
List tempList = cloneMyList(newList);
tempList[0]["top"] = 100;
newList[1]["left"] = 300;
print(newList);
print(tempList);
}
List cloneMyList(List originalList) {
List clonedList = new List();
for(Map data in originalList) {
clonedList.add(Map.from(data));
}
return clonedList;
}
This works for me.
Use the fromJson and toJson from your Object's Class on JSON serializing
var copy = ObjectClass.fromJson(OrigObject.toJson());
make a helper class:
class DeepCopy {
static clone(obj) {
var tempObj = {};
for (var key in obj.keys) {
tempObj[key] = obj[key];
}
return tempObj;
}
}
and copy what you want:
List cloneList = [];
if (existList.length > 0) {
for (var element in existList) {
cloneList.add(DeepCopy.clone(element));
}
}
Let's say, you want to deep copy an object Person which has an attribute that is a list of other objects Skills. By convention, we use the copyWith method with optional parameters for deep copy, but you can name it anything you want.
You can do something like this
class Skills {
final String name;
Skills({required this.name});
Skills copyWith({
String? name,
}) {
return Skills(
name: name ?? this.name,
);
}
}
class Person {
final List<Skills> skills;
const Person({required this.skills});
Person copyWith({
List<Skills>? skills,
}) =>
Person(skills: skills ?? this.skills.map((e) => e.copyWith()).toList());
}
Keep in mind that using only this.skills will only copy the reference of the list. So original object and the copied object will point to the same list of skills.
Person copyWith({
List<Skills>? skills,
}) =>
Person(skills: skills ?? this.skills);
If your list is primitive type you can do it like this. Primitive types are automatically copied so you can use this shorter syntax.
class Person {
final List<int> names;
const Person({required this.names});
Person copyWith({
List<int>? names,
}) =>
Person(names: names ?? []...addAll(names));
}
The accepted answer doesn't provide an answer, and the highest-rated answer 'doesn't work' for more complex Map types.
It also doesn't make a deep copy, it makes a shallow copy which seems to be how most people land on this page. My solution also makes a shallow copy.
JSON-cloning, which a few people suggest, just seems like gross overhead for a shallow-clone.
I had this basically
List <Map<String, dynamic>> source = [{'sampledata', []}];
List <Map<String, dynamic>> destination = [];
This worked, but of course, it's not a clone, it's just a reference, but it proved in my real code that the data types of source and destination were compatible (identical in my case, and this case).
destination[0] = source[0];
This did not work
destination[0] = Map.from(source[0]);
This is the easy solution
destionation[0] = Map<String, dynamic>.from(source[0]);
Related
I'm new to dart. I'm trying to covert my Holiday class to Map to be used in my calendar. I tried using Map.fromIterable but it only convert it to <String, dynamic>?
class Occasion {
final List<Holiday> holidays;
Map<DateTime, List> toMap() {
var map = Map.fromIterable(holidays,
key: (e) => DateFormat('y-M-d').format(DateTime.parse(e.date)),
value: (e) => e.name);
print(map);
}
}
class Holiday {
final String date;
final String name;
Holiday({
this.date,
this.name,
});
factory Holiday.fromJson(Map<String, dynamic> parsedJson) {
return Holiday(date: parsedJson['date'], name: parsedJson['name']);
}
}
There are two things:
First: The type parameters of your returned map aren't right for the values you produce in fromIterable. You say it should be List, but in value: ... you are only producing a single String.
Secondly, as I said in my comment you need to help out the dart compiler here a little bit. The compiler isn't very smart. It doesn't see that you are only producing Strings in value. You need to tell him that.
To be fair. This might not be the problem of the compiler, but an overuse of the dynamic type in the collections library.
Map<String, String> toMap() {
var map = Map<String, String>.fromIterable(holidays,
key: (e) => e.date,
value: (e) => e.name );
return map;
}
Just remember: be precise with your types. If you run into type errors start putting additional type information everywhere you can. If you feel it's to cluttered after that, try removing them one spot at a time and see where it leads you.
There is nameof operator in C#, it allows to get property name at compile time:
var name = nameof(User.email);
Console.WriteLine(name);
//Prints: email
It is not possible to use reflection in flutter and I do not want to hardcode names of properties i.e. to be used for querying SQLite tables. Is there any workaround?
***Currently I'm using built_value library.
For the archives, I guess, this isn't possible as Dart doesn't store the names of variables after compiling, and as you mentioned, Flutter doesn't support reflection.
But you can still hardcode responsibly by grouping your properties as part of the object that they belong to, like with JSON:
class User {
final String email;
final String name;
const User({required this.email, required this.name});
Map toJson() => {
"email": email,
"name": name,
};
}
Instead of remembering to type out "email" and "name" whenever you use User, just call User.toJson(). Then, when you want to rename your variables, you can use your IDE's "rename all", or just skim over your User class to quickly change all of the names without missing any.
I'm currently monitoring the progress on the dart:mirrors package, which offers some neat reflective properties and methods, though, I hadn't found a simple way to just get the name of a symbol like nameof() does.
Example:
import 'dart:mirrors';
class User {
final String email;
final String name;
const User({required this.email, required this.name});
}
void main() {
reflectClass(User).declarations.forEach((key, value) {
print(value.simpleName);
});
}
Output:
Symbol("email")
Symbol("name")
Symbol("User")
These are of type Symbol.
More here: https://api.dart.dev/stable/2.4.0/dart-mirrors/dart-mirrors-library.html
So, until they develop a nameof, I've created an extension on symbol:
extension SymbolExtensions on Symbol {
String get nameof =>
RegExp(r'"(.*?)"').firstMatch(toString())!.group(1).toString();
}
So, you could do:
print(reflectClass(User)
.declarations[#email)]!
.simpleName
.nameof);
Output:
email
It's a start. Dart is still growing.
You can use code generation.
The basic idea is to create a nameof annotation class and mark parts of your code with it. You also need to create a code generator that handles your annotated code. Look at the json_serializable package for an example and create your own code generator.
If you do not want to create your own generator, use a ready-made package nameof: https://pub.dev/packages/nameof
Short how-to with this package.
Mark your class with nameof annotation.
#nameof
class Car {
final double price;
final double weigth;
final int year;
final String model;
Car(this.price, this.weigth, this.year, this.model);
Car.sedan(double price, double weigth, int year)
: this(price, weigth, year, 'Sedan');
}
Run the code generator.
flutter pub run build_runner build
Then use the generated class, which will look something like this.
/// Container for names of elements belonging to the [Car] class
abstract class NameofCar {
static const String className = 'Car';
static const String constructor = '';
static const String constructorSedan = 'sedan';
static const String fieldPrice = 'price';
static const String fieldWeigth = 'weigth';
static const String fieldYear = 'year';
static const String fieldModel = 'model';
}
You can implement your own nameOf function:
String? nameOf(dynamic o) {
if (o == null) return "null";
try {
if (o is List) {
var first = o.length > 0 ? o[0] : null;
if (first != null) {
var elementType = nameOf(first)!;
Log.debug("nameOf: List<$elementType>");
if (!isMinified(elementType))
return "List<$elementType>";
}
} else {
Function? getTypeName = o.getTypeName;
if (getTypeName != null) return getTypeName();
}
} catch (e) {
Log.debug("ignored nameOf error: $e, falling back to o.runtimeType: ${o.runtimeType}");
}
return o.runtimeType.toString();
}
bool isMinified(String type) => type.startsWith("minified:");
Code will explain all:
//modal for list
class MyModal
{
int myField1;
List<MyModal> adjacentNodes;
MyModal(this.myField1)
{
adjacentNodes= new List<MyModal>();
}
}
//pre code
List<MyModal> originalList = new List<MyModal>();
originalList.add(new MyModal(1,"firstBuddy"));
//copying list
List<MyModal> secondList = new List<MyModal>();
secondList.addAll(originalList);
//Modifing copy list
secondList.adjacentNodes.add(new MyModal(2,"anotherBuddy"));
//Also modifies original list
print(originalList[0].childs.length); //prints 1, it should prints 0
How can I perform changes in the second list without affecting the original list?
class MyModal {
int myField1;
String myField2;
List<MyModal> adjacentNodes;
MyModal(this.myField1,this.myField2);
MyModal.clone(MyModal source) :
this.myField1 = source.myField1,
this.myField2 = source.myField2,
this.adjacentNodes = source.adjacentNodes.map((item) => new MyModal.clone(item)).toList();
}
var secondList = originalList.map((item) => new MyModal.clone(item)).toList();
If a member of MyModal is of a non-primitive type like String, int, double, num, bool, then the clone() method needs to clone the instances references point to as well.
I think for your use case using immutable values is a better approach, for example with https://pub.dartlang.org/packages/built_value
you can use List.from() function. try this code:
//modal for list
class MyModal {
int myField1;
String name;
List<MyModal> adjacentNodes;
MyModal(this.myField1, this.name) {
adjacentNodes = new List<MyModal>();
}
}
void runCopy() {
//pre code
List<MyModal> originalList = new List<MyModal>();
originalList.add(new MyModal(1, "firstBuddy"));
//copying list
List<MyModal> secondList = List.from(originalList);
secondList.addAll(originalList);
print(originalList);
print(secondList);
}
The recommended way is to use .toList or a list literal.
List<int> source = [1];
List<int> copied = source.toList();
List<int> copied2 = [...source];
I just used thelist2 = thelist1.toList(); and it work
I was having the same problem, List.from() and List.of() didn't work.
I had to map the current list, thus creating a new instance.
List<CompanyBranchesDTO> get companyBranchesCopy {
return companyBranches.map((e) =>
CompanyBranchesDTO(id: e.id, name: e.name, isChecked: e.isChecked))
.toList();
}
That way I have a new instance to inject where it is needed.
Change it to JSON then parse it again to object. I know it's dirty way.
(+) it works and less code.
(-) it not parsing method.
Spread operator allow you to insert values from another list into a collection as explained in the dart language tour:
https://dart.dev/guides/language/language-tour#lists
So you can simply do that to avoid shallow copying:
final List<MyType> newList = [...oldList];
See this dartpad as POC:
https://dartpad.dev/191c4767abc9540c63103044038562da?null_safety=true
List<T>.addall(T) worked for me
i.e.
List<mylist>.addall(oldlist)
Make this extension, put it somewhere.
import 'dart:convert';
extension ListExtensions on List {
get() {
return jsonDecode(jsonEncode(this));
}
}
Basically we need to encode and decode the List so it doesn't refer to the previous List. You can use it like this:
//import your extension
List productList = ["GG FILTER 12","SK KRETEK 12"];
List newProductList = productList.get();
In dart is it possible to instantiate a class from a string?
For example:
vanilla in javascript:
var myObject = window[classNameString];
Objective-C:
id myclass = [[NSClassFromString(#"MyClass") alloc] init];
You need to know the library name and class name to make things work properly. Assume you know both, the below example will instantiate the TestClass and call doStuff on it.
library test;
import "dart:mirrors";
class TestClass {
doStuff() => print("doStuff was called!");
}
main() {
MirrorSystem mirrors = currentMirrorSystem();
LibraryMirror lm = mirrors.libraries['test'];
ClassMirror cm = lm.classes['TestClass'];
Future tcFuture = cm.newInstance('', []);
tcFuture.then((InstanceMirror im) {
var tc = im.reflectee;
tc.doStuff();
});
}
A few notes about this solution:
The library test we are trying to load the class from is already imported in the VM, which makes this case a bit easier.
the call the newInstance allows for passing parameters to the constructor. Positional arguments are implemented, but named parameters are not yet implemented (as of the M2 release).
newInstance returns a Future to allow it to work across isolates.
The syntax has changed.
I got it working this way
library test;
import "dart:mirrors";
class TestClass {
doStuff() => print("doStuff was called!");
}
main() {
MirrorSystem mirrors = currentMirrorSystem();
LibraryMirror lm = mirrors.libraries.values.firstWhere(
(LibraryMirror lm) => lm.qualifiedName == new Symbol('test'));
ClassMirror cm = lm.declarations[new Symbol('TestClass')];
InstanceMirror im = cm.newInstance(new Symbol(''), []);
var tc = im.reflectee;
tc.doStuff();
}
If there are more libraries named 'test' this will fail though.
Try:
Map models = {"Player": Player.instatiate};
var player = models["Player"]();
class Player{
static instatiate() => Player();
}
This was an issue that has plagued me until I figured that I could implement a crude from method to handle the conversion of encoded Json Objects/strings or Dart Maps to the desired class.
Below is a simple example that also handles nulls and accepts JSON (as the string parameter)
import 'dart:convert';
class PaymentDetail
{
String AccountNumber;
double Amount;
int ChargeTypeID;
String CustomerNames;
PaymentDetail({
this.AccountNumber,
this.Amount,
this.ChargeTypeID,
this.CustomerNames
});
PaymentDetail from ({ string : String, object : Map }) {
var map = (object==null) ? (string==null) ? Map() : json.decode(string) : (object==null) ? Map() : object;
return new PaymentDetail(
AccountNumber : map["AccountNumber"] as String,
Amount : map["Amount"] as double,
ChargeTypeID : map["ChargeTypeID"] as int,
CustomerNames : map["CustomerNames"] as String
);
}
}
Below is it's implementation
PaymentDetail payDetail = new PaymentDetail().from(object: new Map());
PaymentDetail otherPayDetail = new PaymentDetail().from(object: {"AccountNumber": "1234", "Amount": 567.2980908});
Once again, this is simplistic and tedious to clone throughout the project but it works for simple cases.
In dart is it possible to instantiate a class from a string?
For example:
vanilla in javascript:
var myObject = window[classNameString];
Objective-C:
id myclass = [[NSClassFromString(#"MyClass") alloc] init];
You need to know the library name and class name to make things work properly. Assume you know both, the below example will instantiate the TestClass and call doStuff on it.
library test;
import "dart:mirrors";
class TestClass {
doStuff() => print("doStuff was called!");
}
main() {
MirrorSystem mirrors = currentMirrorSystem();
LibraryMirror lm = mirrors.libraries['test'];
ClassMirror cm = lm.classes['TestClass'];
Future tcFuture = cm.newInstance('', []);
tcFuture.then((InstanceMirror im) {
var tc = im.reflectee;
tc.doStuff();
});
}
A few notes about this solution:
The library test we are trying to load the class from is already imported in the VM, which makes this case a bit easier.
the call the newInstance allows for passing parameters to the constructor. Positional arguments are implemented, but named parameters are not yet implemented (as of the M2 release).
newInstance returns a Future to allow it to work across isolates.
The syntax has changed.
I got it working this way
library test;
import "dart:mirrors";
class TestClass {
doStuff() => print("doStuff was called!");
}
main() {
MirrorSystem mirrors = currentMirrorSystem();
LibraryMirror lm = mirrors.libraries.values.firstWhere(
(LibraryMirror lm) => lm.qualifiedName == new Symbol('test'));
ClassMirror cm = lm.declarations[new Symbol('TestClass')];
InstanceMirror im = cm.newInstance(new Symbol(''), []);
var tc = im.reflectee;
tc.doStuff();
}
If there are more libraries named 'test' this will fail though.
Try:
Map models = {"Player": Player.instatiate};
var player = models["Player"]();
class Player{
static instatiate() => Player();
}
This was an issue that has plagued me until I figured that I could implement a crude from method to handle the conversion of encoded Json Objects/strings or Dart Maps to the desired class.
Below is a simple example that also handles nulls and accepts JSON (as the string parameter)
import 'dart:convert';
class PaymentDetail
{
String AccountNumber;
double Amount;
int ChargeTypeID;
String CustomerNames;
PaymentDetail({
this.AccountNumber,
this.Amount,
this.ChargeTypeID,
this.CustomerNames
});
PaymentDetail from ({ string : String, object : Map }) {
var map = (object==null) ? (string==null) ? Map() : json.decode(string) : (object==null) ? Map() : object;
return new PaymentDetail(
AccountNumber : map["AccountNumber"] as String,
Amount : map["Amount"] as double,
ChargeTypeID : map["ChargeTypeID"] as int,
CustomerNames : map["CustomerNames"] as String
);
}
}
Below is it's implementation
PaymentDetail payDetail = new PaymentDetail().from(object: new Map());
PaymentDetail otherPayDetail = new PaymentDetail().from(object: {"AccountNumber": "1234", "Amount": 567.2980908});
Once again, this is simplistic and tedious to clone throughout the project but it works for simple cases.