Loopback 4 include relational model in "parent" model - loopbackjs

I'm actually building a REST API with Loopback and I would like to include the civility when I get a person (user).
I created a hasOne relation but on the explorer, the GET /persons/{id}, I have the civilityId but not the civility itself..
Should I create it another way ?
Thanks,

This can be caused by not registering the Relation Resolver or by disabling it.
To register the Relation Resolver, amend the Repository:
export class PersonRepository extends DefaultCrudRepository {
account: HasOneRepositoryFactory<Account, typeof Person.prototype.id>;
constructor(
dataSource: juggler.DataSource,
civilityRepositoryGetter: Getter<CivilityRepository>,
) {
super(Person, dataSource);
// we already have this line to create a HasOneRepository factory
this.civility = this.createHasOneRepositoryFactoryFor(
'account',
civilityRepositoryGetter,
);
// add this line to register inclusion resolver
this.registerInclusionResolver('civility', this.civility.inclusionResolver);
}
}

Related

Nestjs: middleware for all routes except /auth

I am started with nestjs recently and i want apply a middleware for all routes, except the auth route.
In the documentation it says that I can add all the controllers or paths of the routes where I want the middleware, but I find this way quite expensive
.forRoutes(
SearchController,
Other,
Other,
Other
);
So I would like to know if there is a solution, or if you managed to use regex for something like this:
.forRoutes(
{path: 'All route except /auth', method: RequestMethod.ALL}
);
Nowadays we use the function exclude.
export class YourModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(YourMiddleware)
.exclude('auth')
.forRoutes('*');
}
}
For further: https://docs.nestjs.com/middleware#excluding-routes
DOC: https://docs.nestjs.com/middleware
TITLE: Excluding routes
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('*')
consumer.apply(tokenVerify).exclude('/auth').forRoutes('*')
} }
Use /auth/(.*) in case you have routes like /auth/login, /auth/register, etc. .
Exclude route referring exact route path.If you have define global prefix at main.ts,It's also need to come in to that exclude path.
Eg :
main.ts
app.setGlobalPrefix('api/v1');
module.ts
export class YourModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(YourMiddleware)
.exclude({ path:'api/v1/auth',method: RequestMethod.ALL})
.forRoutes('*');
}
}

Symfony4 returning serialized json repsonse

I'm looking at a new Symfony5 project , where I'm trying to return a JSON response of some data.
I have a Project and a ProjectItem
I have the following:
// Project.php
/**
* #ORM\OneToMany(targetEntity="App\Entity\ProjectItem", mappedBy="project")
*/
private $projectItems;
// ProjectItem.php
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Project", inversedBy="projectItems")
*/
private $project;
I have one Project, that can have many ProjectItems
I then have a controller that I'm trying to return a json response:
public function index()
{
$itemsList = $this->getDoctrine()
->getRepository(Project::class)
->findAll();
$items = $this->get('serializer')->serialize($itemsList, 'json');
return new Response($items, 200);
}
This is currently returning an error:
A circular reference has been detected when serializing the object of class "App\Entity\Project" (configured limit: 1)
Am I using the serializer correctly or are my models incorrectly configured?
Simply use json_encode:
public function index()
{
$itemsList = $this->getDoctrine()
->getRepository(Project::class)
->findAll();
return new Response(
json_encode($itemsList),
200
);
}
or use JsonResponse class:
return new JsonResponse($itemsList);
You have a circular reference with your relations. Im guessing ProjectItem has a field project that is referencing Project which causes a loop for the serializer. You can ignore said attribute to prevent this from happening. Checkout the ignored attributes section of the serializer documentation.
Another option would be to use Serialization Groups. Every property would get a Group annotation like for example #Groups("group1") excluding that reference property back to Project.
You would then tell the serializer to serialize that group:
$json = $serializer->serialize(
$itemList,
'json', ['groups' => 'group1']
);
You may also checkout JMS Serializer which adds #Exclude and #Include annotations to make this step a bit easier.

How to add model to PredictionEnginePool in middleware (ML.NET)?

I'm using ML.NET in an ASP.NET Core application, and I am using the following code in Startup:
var builder = services.AddPredictionEnginePool<Foo, Bar>();
if (File.Exists("model.zip"))
{
builder.FromFile(String.Empty, "model.zip", true);
}
If model.zip doesn't exist, I create it later in the middleware. How do I add it to the PredictionEnginePool that is injected?
There are no options to load a model via PredictionEnginePool, and instantiating or injecting a PredictionEnginePoolBuilder isn't an option as it requires IServiceCollection (so must be configured during Startup.ConfigureServices).
The only option I can see at the moment is to set a flag if the file doesn't exist at startup, and then restart the service after model.zip is created in the middleware later on (using IApplicationLifetime.StopApplication), but I really don't like this as an option.
PredictionEnginePool is designed in such a way that you can write your own ModelLoader implementation. Out of the box, Microsoft.Extensions.ML has 2 loaders, File and Uri. When those don't meet your needs, you can drop down and write your own.
See https://github.com/dotnet/machinelearning-samples/pull/560 which changes one of the dotnet/machine-learning samples to use an "in-memory" model loader, it doesn't get the model from a file or a Uri. You can follow the same pattern and write whatever code you need to get your model.
public class InMemoryModelLoader : ModelLoader
{
private readonly ITransformer _model;
public InMemoryModelLoader(ITransformer model)
{
_model = model;
}
public override ITransformer GetModel() => _model;
public override IChangeToken GetReloadToken() =>
// This IChangeToken will never notify a change.
new CancellationChangeToken(CancellationToken.None);
}
And then in Startup.cs
services.AddPredictionEnginePool<ImageInputData, ImageLabelPredictions>();
services.AddOptions<PredictionEnginePoolOptions<ImageInputData, ImageLabelPredictions>>()
.Configure(options =>
{
options.ModelLoader = new InMemoryModelLoader(_mlnetModel);
});

How to inject app.context into Loopback 4 controller

I cannot find any suitable example on how to inject an app.context object into a Loopback 4 controller being in a separate file
This inline example from the documentation works fine
import {inject} from '#loopback/context';
import {Application} from '#loopback/core';
const app = new Application();
app.bind('defaultName').to('John');
export class HelloController {
constructor(#inject('defaultName') private name: string) {}
greet(name?: string) {
return `Hello ${name || this.name}`;
}
}
but I cannot find a way to obtain the same having my controller in a separate file.
I am trying to do something like this:
export class PingController {
constructor(#inject(app.name) private name: string)
app.name being a simple binding in my app-context.
Solution was quite simple.
Since all context values on app level is available throughout the application, no reference to app is required.
I just needed to replace (app.name) with ('name') in the constructor injection.

codeigniter admin template

Hello all im using this template system
http://williamsconcepts.com/ci/codeigniter/libraries/template/index.html
but now i want to add a admin system to it, how would you do that?
make a map in controller/model and view calling "admin" but how can i then use the template system without conflicts :O?.
do you know a better way i will be glad if you will tell :)
Thanks a lot
Yes, you can create a view called admin and a controller called admin; there will be no conflicts.
Using a template library, you will want to do something like this:
In config/template.php
$template['admin']['template'] = 'admin/admin_template.php'; // in your views
// create a new template and its regions
$template['admin']['regions'] = array(
'header',
'content',
'footer',
);
then in your admin controller:
class Admin extends CI_Controller { //ci 2.0
function __construct()
{
parent::__construct();
$this->load->library('template');
$this->template->set_template('admin'); // set the admin template
}
// carry on as normal
}
i set up my routes to go through /admin and the actions that are for admins are in /views/admin/modelname
I also use tankAuth it's very good.