-
When introducing custom methods in #1976 it says:
How exactly do you go about doing that? I have a // users.class.ts
import { Params } from '@feathersjs/feathers/lib';
import { Service, SequelizeServiceOptions } from 'feathers-sequelize';
import app from '../../app';
import { Application } from '../../declarations';
export class Users extends Service {
//eslint-disable-next-line @typescript-eslint/no-unused-vars
constructor(options: Partial<SequelizeServiceOptions>, app: Application) {
super(options);
}
async someTest(data: any, params: Params): Promise<any> {
console.log('Data', data)
console.log('Params, params')
// I can get the data just fine
// I can send stuff back like this
app.service('users').emit('test', {type: 'test', data: { yes: true } })
}
} // users.service.ts
// Initializes the `users` service on path `/users`
import { ServiceAddons, LegacyHookMap } from '@feathersjs/feathers';
import { Application } from '../../declarations';
import { Users } from './users.class';
import createModel from '../../models/users.model';
import hooks from './users.hooks';
// Add this service to the service type index
declare module '../../declarations' {
interface ServiceTypes {
'users': Users;
}
}
export default function (app: Application): void {
const options = {
Model: createModel(app),
paginate: app.get('paginate')
};
// Initialize our service with any options it requires
app.use('users', new Users(options, app), {
methods: ['find', 'get', 'create', 'update', 'patch', 'remove', 'setup', 'someTest'],
events: ['test']
});
// Get our initialized service so that we can register hooks
const service = app.service('users');
service.hooks(hooks);
} The client side is Angular, and I have Feathers configured as an Angular service like this: // feathers.service.ts
import { Injectable, isDevMode } from '@angular/core';
// import * as feathersRx from 'feathers-reactive';
import { io } from 'socket.io-client';
import { feathers, Params } from '@feathersjs/feathers';
import feathersSocketIOClient from '@feathersjs/socketio-client';
import feathersAuthClient2 from '@feathersjs/authentication-client';
import { AuthenticationRequest, AuthenticationResult } from '@feathersjs/authentication/lib';
import { environment } from '@env/environment';
import { Credentials, CredentialsService } from './auth/credentials.service';
import { ActivatedRoute, Router } from '@angular/router';
import { Logger } from '@app/@core';
const log = new Logger('Feathers Service');
/**
* Simple wrapper for feathers
*/
@Injectable({
providedIn: 'root',
})
export class Feathers {
private _feathers = feathers();
private _path = !isDevMode() ? '/socket.io' : '';
private _socket = io(environment.feathersServerUrl, {
path: this._path,
});
private feathersAuthClient = require('@feathersjs/authentication-client').default;
constructor(private credentialsService: CredentialsService, private router: Router, private route: ActivatedRoute) {
this._feathers.configure(feathersSocketIOClient(this._socket)).configure(this.feathersAuthClient());
this._feathers.io.on('connect', () => {
if (!this._feathers.authentication.authenticated) {
this._feathers.reAuthenticate()
}
})
this._feathers.on('disconnect', (result: any) => {
console.log('Disconnected', result)
})
this._feathers.on('authenticated', (result: AuthenticationResult) => {
console.log('Authenticated!')
const credentials: Credentials = {
username: result.user.username,
token: result.accessToken,
};
this.credentialsService.setCredentials(credentials);
this.router.navigate([this.route.snapshot.queryParams.redirect || '/home'], { replaceUrl: true });
});
// .configure(
// feathersRx({
// idField: '_id',
// })
// );
this._feathers.on('login', (result: AuthenticationResult) => {
this._socket.emit('patch', 'users', result.user.id, {
is_logged_in: true
}, (error: any, message: any) => {
console.log('Patched message', message);
});
})
this._feathers.on('logout', (result: any) => {
this._socket.emit('patch', 'users', result.user.id, {
is_logged_in: false
}, (error: any, message: any) => {
console.log('Patched message', message);
});
})
}
// expose services
public service(name: string) {
return this._feathers.service(name);
}
// expose authentication
public authenticate(credentials?: AuthenticationRequest): Promise<AuthenticationResult> {
return this._feathers.authenticate(credentials);
}
// expose reauthentication
public reAuthenticate(strategy?: string): Promise<AuthenticationResult> {
return this._feathers.reAuthenticate(false, strategy);
}
// expose logout
public logout() {
return this._feathers.logout();
}
// expose custom service methods
public async emit(method: string, service: string, data: any, params: Params): Promise<any> {
let result = this._feathers.io.emit(method, service, data, params)
this._feathers.service('users').on('test', result => {
log.info('Result', result)
return result
})
}
} With that setup I can call something like How should this be setup on the client side so that I can call the custom service method? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
There's some more info in the referenced PR at #2270. So for both TS and JS you'd have to tell the client that the service has that method: // In your case in the constructor after setting up the Feathers app
this._feathers.service('users').methods('someTest'); To also get the client side TypeScript types you'd do: import { feathers, CustomMethod } from '@feathersjs/feathers';
import socketio, { SocketClient } from '@feathersjs/socketio-client';
type ServiceTypes = {
users: SocketClient & CustomMethod<'someTest'>
}
export class Feathers {
private _feathers = feathers<ServiceTypes>();
// ...
} |
Beta Was this translation helpful? Give feedback.
There's some more info in the referenced PR at #2270. So for both TS and JS you'd have to tell the client that the service has that method:
To also get the client side TypeScript types you'd do: