ng-admin: embedded_list reference fields do not work

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 }),

About this issue

  • Original URL
  • State: open
  • Created 9 years ago
  • Reactions: 11
  • Comments: 20 (5 by maintainers)

Most upvoted comments

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 😃

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
];

`

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.

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.

+1 seriously need! is there any workaround?