JayData Data model already created - add an OData action afterwards - t4

I have an OData Web Api service where I create the controllers with a T4 template from the EF datamodel.
While doing that, I also create the Jaydata datamodel with T4.
But now, I have a partial class that will add an action to one of my controllers.
As the JayData file is also created by a T4 template, is there a way to add actions to one of the EntitySets later on?

What I managed to do now is the following:
My generated JayData context looks like the following:
$data.EntityContext.extend('myNameSpace.MyContext', {
'Cases': { type: $data.EntitySet, elementType: myNameSpace.Case},
// ... other Entitysets
}
Later, I extend this context like this:
myNameSpace.MyContext.extend('myNameSpace.MyExtendedContext', {
'Cases': { type: $data.EntitySet, elementType: myNameSpace.Case, actions: {
'Checkout': { type: $data.ServiceAction, returnType: 'myNameSpace.Case', IsBindable: true, 'EntitySet': 'Cases', IsAlwaysBindable: true, params: [{ name: 'Id', type: 'Edm.Guid' }] }
}
}
So I can use my action if I later use my extended context. I think this should be good enough.
My Typescript definitions for this look like this:
declare module myNamespace {
export class CaseExtensions extends $data.EntitySet<myNamespace.Case> {
Checkout: {
(Id: string, handler?: (result: myNamespace.Case) => void): $data.IPromise<Case>;
(params?: { Id?: string; }, handler?: (result: myNamespace.Case) => void): $data.IPromise<Case>;
};
}
export class MyExtendedContext extends MyContext {
Cases: CaseExtensions;
}
}

Related

How to use sequelize-typescript for querying relative objects through custom Apollo GraphQL resolver?

How to use sequelize-typescript for querying relative objects through custom Apollo GraphQL type? I have the following query without typescript:
User and Event GraphQL types:
type User {
id: Int
login: String
email: String
role: Roles
url_identity: String
}
type Event {
id: Int
event_name: String
user: User
}
User model
import {HasOne, Model, Table} from "sequelize-typescript";
import Event from "./event.model";
#Table({
timestamps: false,
modelName: 'User',
})
export default class User extends Model {
#HasOne(() => Event)
event: Event
}
Resolver:
static resolver() {
return {
Event: {
user: event => event.$get('user')
}
}
Typescript can't see event.$get('user')
The answer is to add mappers to your graphql-codegen config.
You can also pass interface for context (third parameter):
schema: ./src/graphql/types/**/*.graphql
generates:
./src/graphql/resolvers-types.ts:
config:
useIndexSignature: true
contextType: ./schema#IApolloServerContext
mappers:
Event: ../database/models/event.model#EventModel
User: ../database/models/user.model#UserModel
plugins:
- typescript
- typescript-resolvers
More info here: https://graphql-code-generator.com/docs/plugins/typescript-resolvers#use-your-model-types-mappers

How to retrieve dropdown items from an observable?

How would you retrieve dropdown items from an observable in #rxweb/reactive-dynamic-forms ?
how do you inject service in FormControlConfig subclass? shared code here https://stackblitz.com/edit/angular-bs5yqt-nmzcwj
For injecting custom services into the dynamic form control source model you have to pass the respective service into the argument of model configuration.
Step 1
Create a Service according to your need, I am creating fake ConfigService.
import { HttpClient} from "#angular/common/http"
import { Injectable } from "#angular/core"
#Injectable()
export class ConfigService {
constructor(private http: HttpClient) { }
configUrl = 'assets/config.json';
getConfig() {
return this.http.get(this.configUrl);
}
}
Step 2
Let's create a Model, which is extended with FormControlConfig for async source binding.
import { FormControlConfig } from "#rxweb/reactive-dynamic-forms"
import { ConfigService } from "./config.service"
export class SourceAsyncConditionalModel extends FormControlConfig{
constructor(fieldConfig: { [key: string]: any }, public controlsConfig: { [key: string]: FormControlConfig },notificationId:number,private configService:ConfigService){
super(fieldConfig,controlsConfig,notificationId);
}
filter() {
let promise = new Promise<any>((resolve, reject) => {
/// call the service
if(this.configService)
this.configService.getConfig();
});
}
}
If you see the above the code where I have defined four parameters. The first three parameters are used in FormControlControl and the fourth parameter we can use in the model instance.
Step 3
Now, we have to pass the parameter with respective model. See the below code :
this.dynamicFormConfiguration = {
controlConfigModels: [{ modelName: 'sourceAsync', model: SourceAsyncConditionalModel,arguments:[this.configService] }],
}
this.dynamicFormBuildConfig = this.formBuilder.formGroup(this.serverData, this.dynamicFormConfiguration);
Here is the working Example

Hapijs Joi reference schema keys to reuse in other models or in routes

I have an example model constructed like so:
const MyModelResponse = Joi.object().keys({
id: Joi.number().integer().required()
.description('ID of the example model'),
description: Joi.string()
.description('Description of the example model'),
})
.description('example instance of MyModel with the unique ID present')
.label('MyModelResponse');
In my route, I want to make sure that my input parameter is validated against the id property of MyModeResponse like so:
validate: {
params: {
id: MyModelResponse.id,
},
options: { presence: 'required' },
failAction: failAction('request'),
}
This results in the schema validation error upon server start:
AssertionError [ERR_ASSERTION]: Invalid schema content: (id)
Is there a way to reference a key of a schema? Currently, I have to resort to either of the following:
Not referencing my MyModelResponse schema at all:
validate: {
params: {
id: Joi.number().integer().description('id of MyModel instance to get'),
},
options: { presence: 'required' },
failAction: failAction('request'),
}
Not using the Joi.object.keys() constructor by defining my model like this:
const MyModelResponse = {
id: Joi.number().integer().required()
.description('ID of the example model'),
description: Joi.string()
.description('Description of the example model'),
}
The bottom approach allows me to reference the id property in my route but doesn't allow me to add descriptions and labels to my schema. I have tried using MyModel.describe().children.id in my route validation and I have made some attempts to deserialize the id object into a schema object to no avail.
Any suggestions would be appreciated.
Remove the keys() and use as follows
const MyModelResponse = Joi.object({
id: Joi.number().integer().required()
.description('ID of the example model'),
description: Joi.string()
.description('Description of the example model'),
})
.description('example instance of MyModel with the unique ID present')
.label('MyModelResponse');

GraphQL scheme delegation: info.mergeInfo is not defined

I wonder if there is a catch to using info.mergeInfo when delegating a resolver. To explain what I'm trying to do let's assume a schema similar to:
type Repository {
id: Int!
commits: [Commit!]!
}
type Commit {
id: Int!
repository: Repository!
}
I'm trying to implement a query similar to:
query {
RepositoryByCommit($id: Int!) {
commit(id: $id) {
repository {
id
}
}
}
}
With a resolver like:
Query: {
repository: (_, { id }) => db.getRepository(id),
commit: (_, { id }) => db.getCommit(id)
},
Commit: {
repository: (repository, args, context, info) {
return info.mergeInfo.delegate({ // <-- mergeInfo is undefined here
operation: 'query',
fieldName: 'repository',
args: {
id: context.commitRawDBEntity.repositoryId
}
})
}
}
Now according to graphql-tools documentation there should be a set of functions available on info.mergeInfo for all resolvers. But in my case there is no property called info.mergeInfo nor anything similar.
It's worth to mention that I'm using makeExecutableSchema from graphql-tools to serve this GraphQL endpoint so I had the reason to assume that graphql-tools somehow would add that functionality to all resolvers.
Am I doing it all wrong? Why don't I have a mergeInfo object in my resolver? Are there better ways to achieve a resolution of parent entity?
Thanks !

How to extend the NavigationListItem control in SAPUI5?

I want to extend the NavigationListItem control to accept sap.ui.core.Control objects in it's aggregation. I have created a separate file to extend the control and added a new aggregation called 'rows' with type sap.ui.core.Control in the metadata section. The extended control is getting called in the view, but it is not displaying any child controls which were added to the new aggregation 'rows'. Please advise, if I need to add anything more to the extension file.
Extension code:
sap.ui.define(["sap/ui/core/Control",
"sap/tnt/NavigationListItem"],
function(Control, NavigationListItem) {
"use strict";
return NavigationListItem.extend("ajacontrolExt.control.NavigationCustomListItem", {
metadata: {
properties: {
},
defaultAggregation: "rows",
aggregations: {
rows: {
type: "sap.ui.core.Control",
multiple: true,
singularName: "row"
}
}
}
});
});

Resources