Search code examples
javascriptangularjsodata

how to properly specify nested OData $expand to Angular $odataresource directive?


In my Angular app I'm using $odataresource directive to consume OData v4 feed in the following way:

http://10.0.0.4:8080/InformationProduct?$expand=DataEntities($expand=DataSources)

This query runs fine in Fiddler, Postman, as well as any modern browser:

{
    @odata.context: "http://10.0.0.4:8080/$metadata#InformationProduct",
    value: [{
        ID: 1,
        Name: "ODM Dashboard",
        Description: "ODM Dashboard",
        Governance_ID: 1,
        PerformanceMetric_ID: 1,
        DataEntities: [{
            ID: 1,
            Name: "Data Entity 1",
            Description: "Data Entity 1",
            InformationProduct_ID: 1,
            BiMeasure_ID: null,
            BiFact_ID: null,
            BiDimension_ID: 1,
            DataSources: [{
                ID: 40,
                Category: "Service Performance",
                SourceSystemName: "Account Improvement Plan",
                SourceSystemOwner: null,
                SourceSystemLocation: null,
                SourceSystemTeam: null,
                SourceSystemNetworkSegment: null,
                SourceSystemOsType: null,
                SourceDatabaseName: null,
                SourceDatabaseType: null,
                SourceDatabaseVersion: null,
                BiFact_ID: null
            }]
        }]
    }]
}

I'm trying to implement the same query within my Angular controller like this:

function getData(){
    $odataresource("http://windows-10:8080/InformationProduct")
        .odata()
        .expand('SourceTools')
        .expand('DataEntities','DataSources')
    {}
}

I'm getting this error:

GET http://windows-10:8080/InformationProduct?$expand=SourceTools,DataEntities/DataSources 400 (Bad Request)

It is clear, that $odataresource does not translate .expand('DataEntities','DataSources')

into $expand=DataEntities($expand=DataSources) as expected

What is the proper way to have $odataresource directive produce such nested $expand?


Solution

  • The docs state that you need to use the isodatav4 property to let it know that you are using a v4 endpoint:

    To enable this behavior set the isodatav4 property to true when invoking the $odataresource method:

    User = $odataresource('/user', {}, {}, {
        odatakey: 'id',
        isodatav4: true
    });
    

    Then use the expand method like this:

    var result = User.odata().expand("roles", "role").query();
    //  /user?$expand=roles($expand=role)
    

    For you, this means that you have the right expand call already, you just need to add the isodatav4 flag to $odataresource("http://windows-10:8080/InformationProduct") to make $odataresource("http://windows-10:8080/InformationProduct", {}, {}, { isodatav4: true })