ng-admin icon indicating copy to clipboard operation
ng-admin copied to clipboard

embedded_list reference fields do not work

Open jamespsterling opened this issue 9 years ago • 20 comments

I have an edit view with an embedded list field that has sub-fields of reference type and they do not work properly. There is no call to the rest api asking for the list in this example.

        nga.field('editResultsId', 'embedded_list')
            .label('Edit Results')
            .targetFields([
                nga.field('fileSystemId', 'reference')
                    .label('File System')
                    .targetEntity(file)
                    .targetField(nga.field('name'))
                    .validation({ required: true }),

jamespsterling avatar Nov 13 '15 21:11 jamespsterling

Hi, which version of ng-admin are you using? This has been added to 0.9.

fzaninotto avatar Nov 13 '15 21:11 fzaninotto

I'm using 0.9, just did a fresh pull too

jamespsterling avatar Nov 13 '15 21:11 jamespsterling

For clarification, it's the fileSystem reference child on this embedded list entity that does not populate. is this a bug?

jamespsterling avatar Nov 16 '15 16:11 jamespsterling

Ah ok, now I get it: it's the file dropdown that is empty, is that it? Then it's just not implemented yet.

fzaninotto avatar Nov 16 '15 16:11 fzaninotto

Yes, that's the issue.

jamespsterling avatar Nov 16 '15 16:11 jamespsterling

+1 would be very helpful indeed!

clems71 avatar Jan 19 '16 22:01 clems71

Just stumbled over the same problem with reference_many inside a embedded_list.

xteron avatar Mar 01 '16 12:03 xteron

I am not sure this is the same problem. I am trying to reference a object with nested ids. Maybe someone can help?

Object with nested references:

{"user":
  "id": 1,
  "orders": [
    {"order_id: 100},
    {"order_id": 101}
  ]
}

The code below returns the following error

(state change error: e.targetField(...).name is not a function)

user.showView().fields([
    nga.field('orders.id', 'reference_many')
          .targetEntity(order)
          .targetField('id')
]);

(BTW, great project! Having an admin tool that works against the backend-logic instead of directly to the DB is truly cool).

NadavK avatar Mar 06 '16 16:03 NadavK

+1 seriously need! is there any workaround?

mosasiru avatar Apr 20 '16 08:04 mosasiru

@NadavK I don't have a solution for the opened issue (which I also need solved). But your error is because you don't have targetField('id') in a field definition: targetField(nga.field('id')) I think.

collinforrester avatar Jun 24 '16 14:06 collinforrester

+1 need it too, would be really great :)

MaxTwentythree avatar Jul 01 '16 13:07 MaxTwentythree

Some notes from my duplicate over at #1145 (sorry, closed now!)

I can confirm this is still an issue in 1.0.0-alpha4

  1. showView does not perform any retrievals of reference objects for rendering
  2. creationView and editionView both load listings and perform remote completion as expected
  3. editionView does not retrieve the reference object for rendering. However if the object is returned in the listing of objects used to render the dropdown, this does work as expected.

dowlingw avatar Jul 07 '16 07:07 dowlingw

I had a quick look at this today but wasn't able to make much progress - had to figure out how things hang together. Leaving some notes as @etdev was keen to look at this also.

Crud/routing.js creates a bunch of ui-router resolve definitions based on the model coming out of the admin-config library.

It looks like lib/Utils/ReferenceExtractor in admin-config is the culprit, it only looks at the top level object and doesn't traverse complex fields.

Took a quick stab at fixing this but I've run out of time to look at it this week and it doesn't work. Here's the code so far, it's a recursive function to find all the reference fields during a call to getReferences.

let find_references = function(fields, recurse_func) {
    let result = new Array();

    fields.forEach(function(field, idx) {
        if( field.type() === 'reference' || f.type() === 'reference_many' ) {
            result.push(field);
        } else if( field.type() === 'embedded_list' ) {
            result.push( recurse_func( field.fields(), recurse_func ) );
        }
    });

    return result;
};
let references = find_references(fields,find_references);

Cheers :)

dowlingw avatar Jul 07 '16 09:07 dowlingw

Any news on this? I ran into the same issue...

underdoeg avatar Oct 20 '16 21:10 underdoeg

Same problem.

It seems that the referenced entity is not requested according to the Network tab of chrome Developer tool.

huiyiqun avatar Oct 27 '16 16:10 huiyiqun

WORKAROUND -- While waiting for the pull-request to be completed, I found an easy workaround. Just add the same reference field to your top level object (make it hidden, non-editable, not required). As long as you use the same object in .targetEntity() in both the top level and embedded, you will get a populated list. Below I just used an empty label and non-editable field, but you can use CSS to hide the field row as well.

`
var wtEntity = nga.entity('webapp_templates');
var embeddedFields = [
        nga.field('webapp_template', 'reference')
            .targetEntity(wtEntity)
            .validation({required: true})
            .targetField(nga.field('context_name'))
            .detailLinkRoute('show'),
        ...  //Other embedded fields
];
var parentFields = [
        nga.field('webapps', 'embedded_list')
            .targetFields(embeddedWebappsFields),
    ...  //Other parent fields
        nga.field('webapp_template', 'reference')   //Workaround for reference in embedded list
            .targetEntity(wtEntity)  //Same entity object, not just another entity with the same name
            .editable(false)  //non-editable keeps the control from showing
            .label('')  //no label
            .validation({required: false})  //not required so it won't error
            .targetField(nga.field('context_name')),  //not sure this is needed, but I left it
];

`

jbrownD3 avatar Nov 22 '16 15:11 jbrownD3

I found a further problem with reference fields. I followed jbrownD's instructions and they worked great. However I found if I have a bad reference (e.g I have web app templates 1,2,3 but I have a reference to template 4) I get empty lists for all the dropdown lists on my page (even the "good" ones) and I get a traceback: Error: undefined is not an object (evaluating 'e.values') http://localhost:3000/asset/ng-admin.min.js:15:14427 It's easily resolved by making sure there are no referential integrity issues in the data, but it's one thing to look out for

DerekK19 avatar Mar 06 '17 23:03 DerekK19

This just worked for me:

nga.field('products', 'embedded_list')
        .label('Product in Discount')
        .targetFields([
          nga.field('product', 'reference')
            .label('Product')
            .targetEntity(admin.getEntity('products'))
            .targetField(nga.field('name'))
            .singleApiCall(ids => ({'_id': ids }))
            .remoteComplete(true),

The singleApiCall can be ommited I think, because it's just for MongoDB.

matheo avatar Mar 09 '17 04:03 matheo

I tried to fix it by this PR https://github.com/marmelab/admin-config/pull/75

mosasiru avatar Mar 09 '17 04:03 mosasiru

is there any solution for this issue ??

vinhtd2 avatar Apr 23 '19 04:04 vinhtd2