'Can't access object field after eager loading in Laravel 8

When I'm trying to eager load my Model with relation like that:

$plants = Plant::with('history')
    ->get()
    ->where('user_id', auth()->id());

I want to modify those extracted dates with my function like that:

foreach ($plants as $plant) {
        $plant->watered_at = self::getDateForHumans($plant->history->watered_at);
        $plant->fertilized_at = self::getDateForHumans($plant->history->fertilized_at);
    }

I get this kind of error:

ErrorException Trying to get property 'watered_at' of non-object

but if I try to debug it by dd() function i get a positive result

   dd(self::getDateForHumans($plant->history->watered_at));

dd() result

Does anybody know how to fix it or what is the workaround?



Solution 1:[1]

Escapes processed by compiler

The escapes embedded in a string literal are processed by the compiler, and transformed as the intended character. So at runtime, the string object contains a null, and does not contain a backslash and zero seen in your literal "an\0Example".

You can see this in the following code.

    String input = "an\0Example" ;
    System.out.println(
        Arrays.toString(
            input.codePoints().toArray()
        )
    );

See this code run live at IdeOne.com. Notice the zero in third position, a null character, followed by the seven characters of the word “Example”.

[97, 110, 0, 69, 120, 97, 109, 112, 108, 101]

Avoid char

Never use char type. That type has been legacy as of Java 2, essentially broken. As a 16-bit value, char is physically incapable of representing most characters.

Code points

Use code point integer numbers instead.

StringBuilder sb = new StringBuilder() ;
for( int codePoint : input.codePoints().toArray() ){
    if( ! Character.isISOControl( codePoint ) ) {
        sb.appendCodePoint( codePoint ) ;
    }
 }
String output = sb.toString() ;

Dump to console.

System.out.println( output ) ;
System.out.println( Arrays.toString( output.codePoints().toArray() ) ) ;
}
System.out.println( output.codePoints().mapToObj( Character :: toString ).toList() ) ;

See this code run live at IdeOne.com.

anExample

[97, 110, 69, 120, 97, 109, 112, 108, 101]

[a, n, E, x, a, m, p, l, e]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1