![Create React App Officially Deprecated Amid React 19 Compatibility Issues](https://cdn.sanity.io/images/cgdhsj6q/production/04fa08cf844d798abc0e1a6391c129363cc7e2ab-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Create React App Officially Deprecated Amid React 19 Compatibility Issues
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
@beradrian/ngx-resource-core
Advanced tools
Resource Core is an evolution of ngx-resource lib which provides flexibility for developers. Each developer can implement their own request handlers to easily customize the behavior.
In fact, @ngx-resource/core
is an abstract common library which uses ResourceHandler
to make requests, so it's even possible to use the lib on node.js server side with typescript. You just need to implement a ResourceHandler
for it.
All my examples will be based on angular 4.4.4+
@ngx-resource/handler-ngx-http
. Based on HttpClient
from @angular/common/http
. Includes ResourceModule.forRoot
.@ngx-resource/handler-ngx-http-legacy
. Based on Http
from @angular/http
. Includes ResourceModule.forRoot
.@ngx-resource/handler-cordova-advanced-http
. Based on Cordova Plugin Advanced HTTP.@ngx-resource/handler-fetch
. Besed on Fetch API. Not yet created.@Injectable()
@ResourceParams({
// IResourceParams
pathPrefix: '/auth'
})
export class MyAuthResource extends Resource {
@ResourceAction({
// IResourceAction
method: ResourceRequestMethod.Post,
path: '/login'
})
login: IResourceMethod<{login: string, password: string}, IReturnData>; // will make an post request to /auth/login
@ResourceAction({
// IResourceAction
//method: ResourceRequestMethod.Get is by default
path: '/logout'
})
logout: IResourceMethod<void, void>;
constructor(handler: ResourceHandler) {
super(handler);
}
}
@Injectable()
@ResourceParams({
// IResourceParams
pathPrefix: '/user'
})
export class UserResource extends Resource {
@ResourceAction({
path: '/{!id}'
})
getUser: IResourceMethod<{id: string}, IUser>; // will call /user/id
@ResourceAction({
method: ResourceRequestMethod.Post
})
createUser: IResourceMethodStrict<IUser, IUserQuery, IUserPathParams, IUser>;
@ResoucreAction({
path: '/test/data',
asResourceResponse: true
})
testUserRequest: IResourceMethodFull<{id: string}, IUser>; // will call /test/data and receive repsponse object with headers, status and body
constructor(restHandler: ResourceHandler) {
super(restHandler);
}
}
// Using created Resource
@Injectable
export class MyService {
private user: IUser = null;
constructor(private myResource: MyAuthResource, private userResource: UserResource) {}
doLogin(login: string, password: string): Promise<any> {
return this.myResource.login({login, password});
}
doLogout(): Promise<any> {
return this.myResource.logout();
}
async loginAndLoadUser(login: string, password: string, userId: string): Promise<any> {
await this.doLogin(login, password);
this.user = await this.userResource.getUser({id: userId});
}
}
Final url is generated by concatination of $getUrl
, $getPathPrefix
and $getPath
methods of Resource
base class.
Is used by ResourceParams
decorator for class decoration
List of params:
url?: string;
- url of the api server; default ''
pathPrefix?: string;
- path prefix of the api; default ''
path?: string;
- path of the api; default ''
headers?: any;
- headers; default {}
body?: any;
- default body; default null
params?: any;
- default url params; default null
query?: any;
- defualt query params; default null
rootNode?: string;
- key to assign all body; default null
removeTrailingSlash?: boolean;
- default true
addTimestamp?: boolean | string;
- default false
withCredentials?: boolean;
- default false
lean?: boolean;
- do no add $
properties on result. Used only with toPromise: false
default false
mutateBody?: boolean;
- if need to mutate provided body with response body. default false
asPromise?: boolean;
- if method should return promise or object, which will be fullfilled after receiving response. default true
asResourceResponse?: boolean;
- Receive IResourceResponse
as a body . default false
keepEmptyBody?: boolean;
- if need to keep empty body object {}
requestBodyType?: ResourceRequestBodyType;
- request body type. default: will be detected automatically.
Check for possible body types in the sources of ResourceRequestBodyType. Type detection algorithm check here.responseBodyType?: ResourceResponseBodyType;
- response body type. default: ResourceResponseBodyType.JSON
Possible body type can be checked here ResourceResponseBodyType.Is used by ResourceAction
decorator for methods.
List of params (is all of the above) plus the following:
method?: ResourceRequestMethod;
- method of request. Default ResourceRequestMethod.Get
. All possible methods listed in ResourceRequestMethodexpectJsonArray?: boolean;
- if expected to receive an array. The field is used only with toPromise: false
. Default false
.resultFactory?: IResourceResultFactory;
- custom method to create result object. Default: returns {}
map?: IResourceResponseMap;
- custom data mapping method. Default: returns without any changes
filter?: IResourceResponseFilter;
- custom data filtering method. Default: returns true
Mainly used to set defaults.
An object with built-in in methods to save, update, and delete a model.
Here is an example of a User
model.
Note: UserResource should be injected at the beginning in order to use static
model method like User.get(<id>)
, User.query()
, User.remove(<id>)
export interface IPaginationQuery {
page?: number;
perPage?: number;
}
export interface IGroupQuery extends IPaginationQuery {
title?: string;
}
export interface IUserQuery extends IPaginationQuery {
firstName?: string;
lastName?: string;
groupId?: number;
}
export interface IUser {
id: number;
userName: string;
firstName: string;
lastName: string;
groupId: string;
}
export class GroupResource extends ResourceCRUD<IGroupQuery, Group, Group> {
constructor(restHandler: ResourceHandler) {
super(restHandler);
}
$resultFactory(data: any, options: IResourceActionInner = {}): any {
return new Group(data);
}
}
export class Group extends ResourceModel {
readonly $resource = GroupResource;
id: number;
title: string;
constructor(data?: IGroup) {
super();
if (data) {
this.$setData(data);
}
}
$setData(data: IGroup) {
this.id = data.id;
this.title = data.title;
}
}
export class UserResource extends ResourceCRUD<IUserQuery, User, User> {
constructor(restHandler: ResourceHandler) {
super(restHandler);
}
$resultFactory(data: any, options: IResourceActionInner = {}): any {
return new User(data);
}
}
export class User extends ResourceModel implements IUser {
readonly $resource = UserResource;
id: number;
userName: string;
firstName: string;
lastName: string;
groupId: string;
fullName: string; // generated from first name and last name
constructor(data?: IUser) {
super();
if (data) {
this.$setData(data);
}
}
$setData(data: IUser): this {
Object.assign(this, data);
this.fullName = `${this.firstName} ${this.lastName}`;
return this;
}
toJSON() {
// here i'm using lodash lib pick method.
return _.pick(this, ['id', 'firstName', 'lastName', 'groupId']);
}
}
// example of using the staff
async someMethodToCreateGroupAndUser() {
// Creation a group
const group = new Group();
group.title = 'My group';
// Saving the group
await group.$save();
// Creating an user
const user = new User({
userName: 'troyanskiy',
firstName: 'firstName',
lastName: 'lastName',
groupId: group.id
});
// Saving the user
await user.$save();
// Query data from server
const user1 = await this.userResource.get('1');
// or
const user2: User = await User.get('id');
}
You can define the way query params are converted. Set the global config at the root of your app.
ResourceGlobalConfig.queryMappingMethod = ResourceQueryMappingMethod.<CONVERSION_STRATEGY>
{
a: [{ b:1, c: [2, 3] }]
}
With <CONVERSION_STRATEGY>
being one of the following:
No conversion at all
Output: ?a=[Object object]
All array elements will be indexed
Output: ?a[0][b]=10383&a[0][c][0]=2&a[0][c][1]=3
Implements the standard $.params way of converting
Output: ?a[0][b]=10383&a[0][c][]=2&a[0][c][]=3
Use the ResourceHandler
abstract class as parent to create your Handler. Check the sources of the class for the methods to implement.
FAQs
Core of resource library
The npm package @beradrian/ngx-resource-core receives a total of 1 weekly downloads. As such, @beradrian/ngx-resource-core popularity was classified as not popular.
We found that @beradrian/ngx-resource-core demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.