Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combination of nova-json-wrapper and conditional-container does not work #15

Closed
bintzandt opened this issue Feb 12, 2021 · 10 comments
Closed

Comments

@bintzandt
Copy link

Hi 👋,

I have implemented my resource by extending the abstract class UseJsonWraperAndConditionalContainer as suggested in #10.

However, combining the JsonWrapper and ConditionalContainer does not work. On the front-end, I get the following error: TypeError: this.field.expressionsMap is undefined. This error does not occur when I remove the JsonWrapper (but keep extending the same abstract class).

I read somewhere that this might be caused by incompatibility with Nova version 3.

Are there any plans to add support for newer Nova versions? We are currently using version 3.21.0.

Thanks!

@milewski
Copy link
Member

Hi this error TypeError: this.field.expressionsMap is undefined is caused due that the conditional container trait wasnt included, make sure in the end these 2 traits are included: use HasConditionalContainer; and use HasJsonWrapper;

@bintzandt
Copy link
Author

Like I said, I followed the example in #10.

This is the exact contents of my classes:

class MyResource extends UseJsonWrapperAndConditionalContainer
{
  public function fields(Request $request)
  {
    return [
      JsonWrapper::make('Target', [
        Boolean::make('Collection'),

        ConditionalContainer::make([
          Select::make('Category')->options([
            'a => 'A
            'b' => 'B',
            'c' => 'C',
          ]),
        ])->if('target.collection truthy true'),

        ConditionalContainer::make([
          Multiselect::make('Product')->options(
            Product::orderBy('name')->pluck('name', 'id'),
          )->singleSelect(),
        ])->if('target.collection truthy false'),
      ]),
    ];
  }
}
<?php

namespace App\Nova\Containers;

use DigitalCreative\JsonWrapper\HasJsonWrapper;

abstract class UseJsonWrapperAndConditionalContainer extends UseConditionalContainer
{
    use HasJsonWrapper;
}
<?php

namespace App\Nova\Containers;

use App\Nova\Resource;
use DigitalCreative\ConditionalContainer\HasConditionalContainer;

abstract class UseConditionalContainer extends Resource
{
    use HasConditionalContainer;
}

I still get the error and the ConditionalContainer does not seem to be working. Should I extend the classes the other way around?

@milewski
Copy link
Member

ConditionalContainer cannot depend on a property thats set as its parent.. for example this will not work:

JsonWrapper::make('Target', [
  Boolean::make('Collection'),
  ConditionalContainer::make([])->if('target.collection truthy true')
]);

Because ConditionalContainer is a child of JsonWrapper (this limitation has to do with how the Vue components are created once the payload is sent to the frontend, JsonWrapper is created before ConditionalContainer has a chance to modify it)

This would be the correct way of having this dependency:

JsonWrapper::make('Target', [
  Boolean::make('Collection'),
  ConditionalContainer::make([])->if('collection truthy true')
]);

But I'm unsure if this would work as intended.. due to that JSON wrapper modifies the name of the collection which would confuse the conditional container... try to dd() this line

$child->attribute = "$field->attribute->$child->attribute";
and see what is the value it has been renamed to and see if you can use this name directly on your ->if(name truth true )

@bintzandt
Copy link
Author

try to dd() this line and see what is the value it has been renamed to

It seems like line does not run at all... I have tried using dd, ddd and ray check the contents of that line but none of them works.

But I'm unsure if this would work as intended..

It looks like the use-case in the README.md is the same as mine. It also has ConditionalContainers inside a JsonWrapper. So it probably worked at some point?

Are you sure this has nothing to do with either my Nova version (3.21.0)? Or a conflict in the HasJsonWrapper and HasConditionalContainer traits?

@milewski
Copy link
Member

Try to dd the output this function

return array_merge([ 'fields' => $this->fields ], parent::jsonSerialize());
this is 100% sure to run and contain the attribute name of the field sent back to the frontend

It looks like the use-case in the README.md is the same as mine. It also has ConditionalContainers inside a JsonWrapper. So it probably worked at some point?

Yes it did work, my main point was that you can not depend on a value like this target.collection given that ConditionalContainer is a child of target it should be collection only, as on the example: ->if('gender === male') not ->if('data.gender === male')

@bintzandt
Copy link
Author

this is 100% sure to run and contain the attribute name of the field sent back to the frontend

The name seems to simply be Collection. I have tried using that in the ConditionalContainer but to no avail.

I have created a small Resource to test what is happening.

I can create a JsonWrapper and ConditionalContainer in that Resource without any errors (using the UseJsonWrapperAndConditionalContainer class.

However, the this.field.expressionsMap is undefined error appears when I move the 2 ConditionalContainers inside the JsonWrapper...

See the code examples below.

Working

class TestHighlight extends UseJsonWrapperAndConditionalContainer
{
    public static $model = \App\Highlight::class;

    public function fields(Request $request)
    {
        return [
            Boolean::make('Toggle'),

            ConditionalContainer::make([
                Text::make('True'),
            ])->if('toggle truthy true'),

            ConditionalContainer::make([
                Text::make('False'),
            ])->if('toggle truthy false'),

            JsonWrapper::make('Test', [
                Text::make('Json'),
            ]),
        ];
    }
}

Not working

This examples give the this.field.expressionsMap is undefined error in the JavaScript...

class TestHighlight extends UseJsonWrapperAndConditionalContainer
{
    public static $model = \App\Highlight::class;

    public function fields(Request $request)
    {
        return [
            Boolean::make('Toggle'),

            JsonWrapper::make('Test', [
                Text::make('Json'),

                ConditionalContainer::make([
                    Text::make('True'),
                ])->if('toggle truthy true'),

                ConditionalContainer::make([
                    Text::make('False'),
                ])->if('toggle truthy false'),
            ]),
        ];
    }
}

@milewski
Copy link
Member

I think I found a fix for this, can you try version 1.3.1 https://github.com/dcasia/conditional-container/releases/tag/v1.3.1

@bintzandt
Copy link
Author

Version 1.3.1 seems to work from a functionality point of view.

Loading the page throws an error though.
image

The problem seems to be that the fields property of the JsonWrapper is an Collection while fields in flattenDependencies in the HasConditionalContainer trait is typehinted as an array...

private function flattenDependencies(NovaRequest $request, array $fields)

@milewski
Copy link
Member

Fixed on version v1.3.2

@bintzandt
Copy link
Author

I can confirm that the errors have been resolved. Thank you for you quick responses!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants