# Is there a way to simplify "if (a.prop != null) b.prop = a.prop;"? With a macro perhaps?

**URL:** <https://community.haxe.org/t/is-there-a-way-to-simplify-if-a-prop-null-b-prop-a-prop-with-a-macro-perhaps/3034>\
**Category:** Haxe\
**Created:** [May 14, 2021, 9:28am UTC](https://community.haxe.org/t/is-there-a-way-to-simplify-if-a-prop-null-b-prop-a-prop-with-a-macro-perhaps/3034 "2021-05-14T09:28:39Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![daverave1212](https://community.haxe.org/user_avatar/community.haxe.org/daverave1212/32/1124_2.png) [@daverave1212](https://community.haxe.org/u/daverave1212)\
**Post date:** [May 14, 2021, 9:28am UTC](https://community.haxe.org/t/is-there-a-way-to-simplify-if-a-prop-null-b-prop-a-prop-with-a-macro-perhaps/3034/1 "2021-05-14T09:28:39Z")

</div>

Hello,

I have lots of database reading in code where I set the properties of a normal object to the same property of a Dynamic, only if the Dynamic’s property is not null.

Here’s an example of what I mean:

```
class Dog {
  public var name = 'Default';
  public var age = 0;
  public var owner = 'None';
}

var dynamicDog = {
    name: 'Daisy',
    age: 13
}

```

…

```
var dog: Dog = new Dog();
if (dynamicDog.name != null) dog.name = dynamicDog.name;
if (dynamicDog.age != null) dog.name = dynamicDog.age;
if (dynamicDog.owner != null) dog.owner = dynamicDog.owner;

```

But suppose I have multiple dozens of properties on my class and I need to do this for every single one of them.

What is a preferred solution? Is there a macro for this? I will gladly take non-macro solutions too!

Thanks a lot!

---

<div class="post-metadata">

**Author:** ![Gama11](https://community.haxe.org/user_avatar/community.haxe.org/gama11/32/7_2.png) [@Gama11](https://community.haxe.org/u/Gama11)\
**Post date:** [May 14, 2021, 9:39am UTC](https://community.haxe.org/t/is-there-a-way-to-simplify-if-a-prop-null-b-prop-a-prop-with-a-macro-perhaps/3034/2 "2021-05-14T09:39:37Z")

</div>

I’ve written a macro to do this in the Haxe language server to apply default settings recursively. It’s for structures rather than class instances, but it shouldn’t be too much work to adapt it:

> <https://github.com/vshaxe/haxe-language-server/blob/c53778accdd55c4082f585d0addaf6a37eed82df/src/haxeLanguageServer/helper/StructDefaultsMacro.hx>

Usage:

> <https://github.com/vshaxe/haxe-language-server/blob/cc200727900a7e3c27ae6770f9db898e7a33a068/src/haxeLanguageServer/Configuration.hx#L227>

---

<div class="post-metadata">

**Author:** ![daverave1212](https://community.haxe.org/user_avatar/community.haxe.org/daverave1212/32/1124_2.png) [@daverave1212](https://community.haxe.org/u/daverave1212)\
**Post date:** [May 14, 2021, 9:52am UTC](https://community.haxe.org/t/is-there-a-way-to-simplify-if-a-prop-null-b-prop-a-prop-with-a-macro-perhaps/3034/3 "2021-05-14T09:52:21Z")

</div>

Thanks a lot! Wow, this is pretty cool! Let’s hope it does the job I want. I am fairly new to macros. Any other simpler solution?

---

<div class="post-metadata">

**Author:** ![cambiata](https://community.haxe.org/user_avatar/community.haxe.org/cambiata/32/61_2.png) [@cambiata](https://community.haxe.org/u/cambiata)\
**Post date:** [May 14, 2021, 1:36pm UTC](https://community.haxe.org/t/is-there-a-way-to-simplify-if-a-prop-null-b-prop-a-prop-with-a-macro-perhaps/3034/4 "2021-05-14T13:36:33Z")

</div>

Franco Ponticelli’s thx.core library ([GitHub - fponticelli/thx.core: Super-charged standard library for Haxe.](https://github.com/fponticelli/thx.core)) has a very handy `thx.core.Nulls.or()` method that can be used as static extension.

Example from docs ([GitHub - fponticelli/thx.core: Super-charged standard library for Haxe.](https://github.com/fponticelli/thx.core#nulls)):

```haxe
using thx.Nulls;
function main() {
	var s:String = null;
	trace(s.or('b')); // prints 'b'
	s = 'a';
	trace(s.or('b')); // prints 'a'
	// or more complex
	var o:{a:{b:{c:String}}} = null;
	trace((o.a.b.c).or("B")); // prints 'B'
	var o = {a: {b: {c: 'A'}}};
	trace((o.a.b.c).or("B")); // prints 'A'
}

```

---

<div class="post-metadata">

**Author:** ![filt3rek](https://community.haxe.org/user_avatar/community.haxe.org/filt3rek/32/2613_2.png) [@filt3rek](https://community.haxe.org/u/filt3rek)\
**Post date:** [May 14, 2021, 5:46pm UTC](https://community.haxe.org/t/is-there-a-way-to-simplify-if-a-prop-null-b-prop-a-prop-with-a-macro-perhaps/3034/5 "2021-05-14T17:46:12Z")

</div>

Hej,

I have an old custom function that do also something like that : [Try Haxe !](https://try.haxe.org/#03D7CF01)  
I should rewrite it because I’ve written that years ago, I use it often and it works fine but I think something more clean can be done.

```haxe
using Macro;

class Test {
  static function main() {
    test();
  }
  
  static function test( ?o : Dynamic ){
		trace( o.prop.subProp.ns( "foo" ) ); // "foo"
  }
}

```

---

<div class="post-metadata">

**Author:** ![haxiomic](https://community.haxe.org/user_avatar/community.haxe.org/haxiomic/32/75_2.png) [@haxiomic](https://community.haxe.org/u/haxiomic)\
**Post date:** [May 14, 2021, 6:37pm UTC](https://community.haxe.org/t/is-there-a-way-to-simplify-if-a-prop-null-b-prop-a-prop-with-a-macro-perhaps/3034/6 "2021-05-14T18:37:03Z")

</div>

So there’s two approaches, runtime or compile-time

Runtime is how you’d do this in js – you iterate the fields of `dynamicDog` and check for null before assigning to `Dog`. In haxe, querying fields is done with the [Reflect](https://api.haxe.org/Reflect.html) class:

[live link for this example try.haxe.org/#aF39Ea71](https://try.haxe.org/#aF39Ea71)

```haxe
// copy not-null fields from dog to dynamicDog
for (field in Reflect.fields(dynamicDog)) {
	var value = Reflect.field(dynamicDog, field);
	if (value != null) {
		Reflect.setField(dog, field, value);
	}
}

```

This works, but sometimes (especially if performance matters) you may want to not iterate fields at runtime. So you can generate something like the code you’ve written automatically:

[live link for this example https://try.haxe.org/#F2d0019A](https://try.haxe.org/#F2d0019A)  
**AssignMacro.hx**

```haxe
import haxe.macro.Context;

macro function assign(newValues, target) {
	// let's find out what fields newValues has

	// get the type of the newValues expression
	var newValuesType = Context.typeof(newValues);
	// follow it in to the root type case it's a typedef or abstract
	newValuesType = Context.followWithAbstracts(newValuesType);

	// it could be many types, but we only care about if it's a structure type (TAnonymous)
	switch newValuesType {
		case TAnonymous(aAnon):
			// now we can get all the fields of this type
			var fields = aAnon.get().fields;

			// now we have the field names, we can generate an expression similar to what you're typing out manually
			var assignmentExpressions = [for (field in fields) {
				var fieldName = field.name;
				// rather than assembling the abstract syntax tree for this expression by hand, we can use the macro keyword to turn haxe expressions into syntax nodes
				macro if (newValues.$fieldName != null) target.$fieldName = newValues.$fieldName;
			}];

			// we have an array of assignment expressions, we can combine those to a single block expression using $b{}
			// more about this here: https://haxe.org/manual/macro-reification-expression.html
			return macro {
				// here we give variables names to the expressions so we can reference them in the assignment expressions
				var newValues = $newValues;
				var target = $target;
				$b{assignmentExpressions};
			}
		default:
			Context.fatalError('Expected structure for this argument', newValues.pos);
			return macro null;
	}
}

```

If you use this often, you could add `import AssignMacro` to a file called `import.hx`, then you’ll be able to use `assign()` anywhere, more info: [Import defaults / import.hx - Haxe - The Cross-platform Toolkit](https://haxe.org/manual/type-system-import-defaults.html)

* * *

Given your dynamicDog is almost the same as Dog, just with optional fields, the `Partial<T>` macro might be useful – it takes a type and gives you that type back as a structure type but with all the fields set to optional

> <https://gist.github.com/haxiomic/ad4f5d329ac616543819395f42037aa1>

---

<div class="post-metadata">

**Author:** ![daverave1212](https://community.haxe.org/user_avatar/community.haxe.org/daverave1212/32/1124_2.png) [@daverave1212](https://community.haxe.org/u/daverave1212)\
**Post date:** [May 17, 2021, 12:47pm UTC](https://community.haxe.org/t/is-there-a-way-to-simplify-if-a-prop-null-b-prop-a-prop-with-a-macro-perhaps/3034/7 "2021-05-17T12:47:15Z")

</div>

Thanks all for the answers! I like the approach with Reflection. I don’t mind doing it at runtime.

Cheers everyone!

---

<div class="post-metadata">

**Author:** ![RblSb](https://avatars.discourse-cdn.com/v2/letter/r/edb3f5/32.png) [@RblSb](https://community.haxe.org/u/RblSb)\
**Post date:** [May 17, 2021, 3:47pm UTC](https://community.haxe.org/t/is-there-a-way-to-simplify-if-a-prop-null-b-prop-a-prop-with-a-macro-perhaps/3034/8 "2021-05-17T15:47:33Z")

</div>

`??` operator proposal for reference:

> <https://github.com/HaxeFoundation/haxe-evolution/pull/85>
>
> \[Rendered version\](https://github.com/RblSb/haxe-evolution/blob/null-coalescing/…proposals/0000-null-coalescing.md)

---

<div class="post-metadata">

**Author:** ![AdrianV](https://community.haxe.org/user_avatar/community.haxe.org/adrianv/32/152_2.png) [@AdrianV](https://community.haxe.org/u/AdrianV)\
**Post date:** [May 18, 2021, 12:25pm UTC](https://community.haxe.org/t/is-there-a-way-to-simplify-if-a-prop-null-b-prop-a-prop-with-a-macro-perhaps/3034/9 "2021-05-18T12:25:47Z")

</div>

I have written a small and a bit hacky macro for safe evaluation here: [Try Haxe !](https://try.haxe.org/#29D5CDC6)  
every field that should be checked against `null` must be postfixed with `!`. If one of the checks fails, it returns the optional `default` value - or `null` if no `default` is given.  
Works with method calls too - here first the method field is checked for existence and after the call the result - so something like this `trace(Macro.safe(f!.bar()!.foo("bar")!.b, 42))` evaluates safely.  
I am not good in writing macros - I am sure it can be done more elegant 🙂
