On loopback4, how can I avoid Circular Dependency when model B (reports) needs to check all model A (order) data?

My loopback4 project contains two models:

Order - Order contains hasMany Report

Report - Report belongsTo Order

On ReportRepository.newReport method, I need to find and manipulate all data of Order, including reports. And this causes Circular Dependency.

How can I avoid this error?

Already tryed:

@bind({scope: BindingScope.SINGLETON}) -

How to implement chained models with loopback 4 without getting a Circular dependency

Passes Circular Dependency but creates multi-tenancy issues, since I'm using Datasource-based tenant isolation described here https://github.com/strongloop/loopback-next/issues/5056

OrderRepository{ 
    public readonly reports: HasManyRepositoryFactory<Reports, typeof OrdemServico.prototype.id>;

    constructor(
        @repository.getter('ReportRepository')
        protected reportRepositoryGetter: Getter<ReportRepository>
    ){
        this.reports = this.createHasManyRepositoryFactoryFor('reports', reportRepositoryGetter); 
        this.registerInclusionResolver('reports', this.reports.inclusionResolver);
    }

}


ReportRepository {
    public readonly order: BelongsToAccessor<Order, typeof Reports.prototype.id>;

    constructor(
         @repository.getter('OrderRepository') protected orderRepositoryGetter: Getter<OrderRepository>,
    ){
       this.order = this.createBelongsToAccessorFor('order', orderRepositoryGetter,);
    }


    async newReport(nReport: Omit<Report, 'id'>) : PromiseLike<Report> {
       const oRepGet = await orderRepositoryGetter;
       
       return oRepGet.findOne({
              where: {        
                Id: nReport.o
              },
              include: [ { relation: "reports" }]   // <---Line throw Circular Dependency Detected
              
            })
            .then ((rros) => {
            
             .........
             
            }); 
       
    }
}
1

There are 1 best solutions below

0
On

Not the best clean code, but as workaround I:

  • moved and adapted the newReport (child method) to OrderRepository (parent Rep)
  • created a url /orders/newReport
  • changed /reports post method to redirect to OrderRep.newReport

OrderRepository

constructor(
...
 @repository.getter('ReportRepository')
    protected reportRepositoryGetter: Getter<ReportRepository>,
...
)

 async newReport(nReport: Omit<Report, 'id'>) : PromiseLike<Report> {
const repGetter = await reportRepositoryGetter;
       
       return this.findOne({
              where: {        
                Id: nReport.o
              },
              include: [ { relation: "reports" }]   
              
            })
            .then ((rros) => {
            
             .........
              repGetter.create({...})
             
            }); 
       
    }

ReportController:

  @post('/reports', {
...    
  })
  async create(
    ...)
    report: Omit<report, 'id'>,
  ): Promise<OrdemServicoEtapa | null> {
    return this.order.newReport(report);
  }