Coder Social home page Coder Social logo

troyanskiy / ngx-resource Goto Github PK

View Code? Open in Web Editor NEW
200.0 8.0 46.0 5.72 MB

Resource (REST) Client for Angular 2

Home Page: http://troyanskiy.github.io/ngx-resource/

TypeScript 92.32% JavaScript 6.41% HTML 0.94% SCSS 0.33%
angular-2 rest rest-api network requests

ngx-resource's Introduction

Unfortunately I don't have time to maintain the library. So PRs are more than welcome.



@ngx-resource/core @ngx-resource/handler-ngx-http @ngx-resource/handler-cordova-advanced-http @ngx-resource/handler-ngx-http-legacy
npm version npm version npm version npm version

@ngx-resource/core

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+

Known ResourceHandlers

  • @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.

Creation of Resource class

@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: IResourceMethodPromise<{id: string}, IUser>; // will call /user/id
  
  @ResourceAction({
    method: ResourceRequestMethod.Post
  })
  createUser: IResourceMethodPromiseStrict<IUser, IUserQuery, IUserPathParams, IUser>;
  
  @ResoucreAction({
    path: '/test/data',
    asResourceResponse: true
  })
  testUserRequest: IResourceMethodPromiseFull<{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
  • returnAs?: ResourceActionReturnType; - what type response should be returned by action/method . default ResourceActionReturnType.Observable
  • 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 ResourceRequestMethod
  • expectJsonArray?: 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.

Models

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 ResourceCRUDPromise<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 ResourceCRUDPromise<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');
  
}

QueryParams Conversion

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:

Plain (default)

No conversion at all

Output: ?a=[Object object]

Bracket

All array elements will be indexed

Output: ?a[0][b]=10383&a[0][c][0]=2&a[0][c][1]=3

JQueryParamsBracket

Implements the standard $.params way of converting

Output: ?a[0][b]=10383&a[0][c][]=2&a[0][c][]=3

@ngx-resource/handler-ngx-http

It's implementation of ResourceHandler which uses Angular HttpClient

If you are using Angular 5, please use @ngx-resource/handler-ngx-http 5.x

How to install and setup it

& npm i --save @ngx-resource/core @ngx-resource/handler-ngx-http

In you app module

// AoT requires an exported function for factories
export function myHandlerFactory(http: HttpClient) {
    return new MyResourceHandler(http);
}

@NgModule({
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpClientModule,

    // Default ResourceHandler uses class `ResourceHandlerHttpClient`
    ResourceModule.forRoot()
    
    // Or set you own handler
    //ResourceModule.forRoot({
    //  handler: { provide: ResourceHandler, useFactory: (myHandlerFactory), deps: [HttpClient] }
    //})
  ],
  declarations: [...],
  bootstrap: [...],
  entryComponents: [...],
  providers: [...]
})
export class AppModule {
}

ngx-resource's People

Contributors

almothafar avatar beradrian avatar ducminhquan avatar jeremypele avatar komarovalexander avatar mlaffargue avatar spongessuck avatar tarlepp avatar troyanskiy avatar vaidd4 avatar yamaha252 avatar zubb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ngx-resource's Issues

login error, submit data error

servers i used http://www.django-rest-framework.org/
the app login page demo in therehttp://restframework.herokuapp.com/api-auth/login/?next=/

i want use ng2-resource-rest login that

but, ng2-resource-rest submit data have question

i capture Chrome login data:
submit data is:csrfmiddlewaretoken=G71nGgFwhUyguxhdNz8c6DdWLHDKKr6K&username=111111111&password=112222222222222&next=%2F&submit=Log+in


i use ng2-resource-rest:
code :

 this.Res.login("csrfmiddlewaretoken=kgEviC68d6OAB23v5fZlu0e1GO5oig7c&next=&username=111111&password=222222&submit=Log+inName")
                .$observable
                .subscribe(
                  res => console.log(res),
                   err => console.log('Err', err)
               );

i capture Chrome login data:
"csrfmiddlewaretoken=kgEviC68d6OAB23v5fZlu0e1GO5oig7c&next=&username=111111&password=222222&submit=Log+inName"

have quotation marks


then i change i code:

      this.Res.login({username: '111111', password: '222222',csrfmiddlewaretoken:'kgEviC68d6OAB23v5fZlu0e1GO5oig7c',next:'/',submit:'Log+in'})
                .$observable
            .subscribe(
                res => console.log(res),
                err => console.log('Err', err)
            );

i capture Chrome login data:
{"username":"111111","password":"222222","csrfmiddlewaretoken":"kgEviC68d6OAB23v5fZlu0e1GO5oig7c","next":"/","submit":"Log+in"}

have {}


so ,login error

would you help me ?

error TS6059 index.ts is not under 'rootDir'

Hi,

I'm working in NativeScript with Angular2 and Typescript project, the problem that when i'm trying to build project I get the following error:

error TS6059: File 'D:/XYZ/Groceries/node_modules/ng2-resource-rest/index.ts' is not under 'rootDir' 'D:/XYZ/Groceries/app'. 'rootDir' is expected to contain all source files.

you can see the tsconfig.json and whole project here :
https://github.com/NativeScript/sample-Groceries

I just installed ng2-resource-rest and I'm trying to use it.

Config:

{
    "compilerOptions": {
        "outDir": "app",
        "rootDir": "app",
        "module": "commonjs",
        "target": "es5",
        "inlineSourceMap": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "emitDecoratorMetadata": true,
        "noEmitOnError": true
    },
    "exclude": [
        "node_modules",
        "platforms"
    ]
}

Type Script errors during preprocessing

Hi,

I'm using @mgechev angular2-seed and I decided to add your ng2-resource-rest component but, on the build process I'm getting the errors I post bellow.
If you need more information about my environment just say what to give you.

node_modules/ng2-resource-rest/index.ts(296,27): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type.
node_modules/ng2-resource-rest/index.ts(349,39): error TS2339: Property 'publish' does not exist on type 'Observable<any>'.

ODATA

This is more like a question than an issue.

I'm trying to use your library along with ODATA. I was thinking that the best way to do it will be to create a ODATAResource class that extends Resource. Then I will override the _getPath method to return the class name. Finally I will implement the ODATA methods as for any resource.

Then when I'll need a specific resource is enough just to extend the ODATAResource and I'll have everything already defined.

What do you think? Is this a good approach?

How to cancel old requests?

Hey,
How I can cancel old request if I call some function of the request second time?
For example if I have get() function and call it twice with different params to cancel the first one and proceed with the second? Observables have swithMap but how I can do it with the ng2-resource-rest?

Use own service in Resource

Hello!
I've got a question.
How can i use my own injactable services in Resource?
This statement breaks extension extension of Resource:

export class UnitRes extends Resource {
    constructor(
            http: Http,
            private _myService: MyService
        ) {
            super(http);
        }
 }

So is there the right way?

Typescript Error

I am getting this error

error TS2320: Interface 'ArrayResourceResult<T>' cannot simultaneously extend types 'ResourceResult' and 'T[]'.
  Named property '$resolved' of types 'ResourceResult' and 'T[]' are not identical.

Reasoning

index.ts -pointing to this line

export interface ArrayResourceResult<T> extends ResourceResult, Array<T> {}

My setup

 tsc -v
Version 1.8.10

Setup for injecting Resources in Lazy Loaded Modules

Hello, so far I really like to use ng2-resource-rest, but I am not sure how to use Resources in lazy loaded modules.
In your guide you load the ResourceModule in the root-module of the application. But when I have lazy loaded feature-modules, the injection of Resources in that feature modules fails. Could you provide an example of how to load ResourceModule properly in such a case? Do I have to use the .forChild() function inside the feature modules? what is the input (subset attribute) for the forChild() function.

Thank you!!!

Using custom Http component

I have my own Http class with name AppHttp which extends from Http.
I found in your code that add2Provides property controls if my resource class is added to the app providers with an instance of the original Http class, so I set it to false, but here comes the problem.
When it is false and In the mine implementation of the Resource class i override its constructor and inject mine Http implementation AppHttp is called twice. The first time it is called with proper backend and defaultOptions arguments but the second time is called with empty backend and defaultOptions which results in the following error TypeError: backend.createConnection is not a function.

What is the right way to use the ng2-resource-rest with mine custom Http implemtation?

constructor(protected http: AppHttp) {
        super(http);
     }

No provider for UserRes! (UserComponent -> UserRes)

EXCEPTION: Error: Uncaught (in promise): No provider for UserRes! (UserComponent -> UserRes)


i got this error
and then

i add UserRes to providers

like this:

  providers: [
        RESOURCE_PROVIDERS,
        UserRes
    ]

then.i got new error:

EXCEPTION: Error: Uncaught (in promise): EXCEPTION: Error during instantiation of UserComponent!.
ORIGINAL EXCEPTION: TypeError: Cannot read property 'request' of undefined
ORIGINAL STACKTRACE:
TypeError: Cannot read property 'request' of undefined
    at UserRes.descriptor.value [as query] (http://127.0.0.1:8888/node_modules/ng2-resource-rest/index.js:166:43)
    at new UserComponent (http://127.0.0.1:8888/app/user/user.component.js:54:46)
    at http://127.0.0.1:8888/node_modules/angular2/bundles/angular2.dev.js:1418:20
    at Injector._instantiate (http://127.0.0.1:8888/node_modules/angular2/bundles/angular2.dev.js:11770:19)
    at Injector._instantiateProvider (http://127.0.0.1:8888/node_modules/angular2/bundles/angular2.dev.js:11709:21)
    at Injector._new (http://127.0.0.1:8888/node_modules/angular2/bundles/angular2.dev.js:11699:19)
    at InjectorInlineStrategy.instantiateProvider (http://127.0.0.1:8888/node_modules/angular2/bundles/angular2.dev.js:11463:28)
    at ElementDirectiveInlineStrategy.init (http://127.0.0.1:8888/node_modules/angular2/bundles/angular2.dev.js:8998:20)
    at new AppElement (http://127.0.0.1:8888/node_modules/angular2/bundles/angular2.dev.js:8688:24)
    at HostViewFactory.viewFactory_HostUserComponent0 [as viewFactory] (viewFactory_UserComponent:73:42)

this my code:

//User.component.ts
import {Resource, ResourceParams} from "ng2-resource-rest";
import {RESOURCE_PROVIDERS} from "ng2-resource-rest";
import {Component} from 'angular2/core';
import {UserRes} from "./user.res";


@Component({
    selector: 'user',
    templateUrl: 'app/user/user.component.html',
    providers: [
        RESOURCE_PROVIDERS,
        UserRes
    ]

})
export class UserComponent {
     allUsers: any[];
    constructor(private Res:UserRes) {       
        this.allUsers = this.Res.query();
    }    
}
//user.res.ts
import {Resource, ResourceParams, ResourceAction, ResourceResult} from "ng2-resource-rest";
import {Injectable} from "angular2/core";
// Make it Injectable
@Injectable()
// Decorate the your resource class
@ResourceParams({
    // Url to api
    url: 'http://127.0.0.1:8888',
    // Api path
    path: '/user/{id}'
})
export class UserRes extends Resource {}

Response header

Hello,

For pagination I have info in the response header, but it seems it is cleared out somehow. I couldn't find the cause. In the responseInterceptor only the content-type remains.

Could you help me?

Thanks

A traling slash "/" after a not mandatory option is removed

If for example I have the following url '/users/{id}' and the the id is null the final url will look line '/users/' which leads to a redirection to '/users' with some APIs, but the redirections are not allowed with CORS requests and leads to following error

XMLHttpRequest cannot load http://example.com/users/. The request was redirected to ' http://example.com/users', which is disallowed for cross-origin requests that require preflight.

this.userRes.remove Err SyntaxError: Unexpected end of JSON input

i used http://www.django-rest-framework.org/

// Will make DELETE request to https://domain.net/api/users/1
            this.userRes.remove({id: 1}) // also alias is availabe to this.userRes.delete
                .$observable
                .subscribe(
                    res => console.log(res),
                    err => console.log('Err', err)
                );

when i DELETE this data,i got a error Err SyntaxError: Unexpected end of JSON input
server return data not json
it return data is null, header is 204,like this:

Request URL:https://127.0.0.1/users/55/
Request Method:DELETE
Status Code:204 No Content
Remote Address:127.0.0.1

dear @troyanskiy ,could help me?

thank you very much

'Supplied parameters do not match any signature of call target' with Resource Model

This is may be more of a documentation update than a real issue, but I wanted to share this workaround in case it helps others. Using a model class that extended from ResourceCRUD, I kept getting a " Supplied parameters do not match any signature of call target" error when trying to do production build with NGC / Ionic build --release. This was on Ionic 2 (RC3) on Angular 2.1.1.

I had created a base resource class as follows:

export class GCResource extends ResourceCRUD<any, any, any>

I was extending it with resource-specific classes, as in UserRes extends GCResource. To get over the "Supplied parameters not matching" message, I had to include an explicit constructor as follows in both my base class and the extender/model classes as in:

constructor(http: Http, injector: Injector) { super(http, injector); }

Just wanted to share this in case it's helpful for future dev or docs. Thanks for a great library!

Angular RC5 trouble

Hello!
On RC4 everything works perfect, but now i've just moved to RC5 and got problems.

I have structure like this:

client
|-app
    |- +question
        |-question.module.ts
        |-question.component.ts

|-shared
    |-shared.module.ts
        |-api
            |-resources
                |-question.res.ts
|-app.module.ts

I've declared my QuestionResource in SharedModule:

export class SharedModule {
    static forRoot(): ModuleWithProviders {
        return {
            ngModule: SharedModule,
            providers: [
                QuestionRes
            ]
        };
    }
}

In QuestionComponent i have:

ngOnInit() {
    this._questionRes.query()
}

And when page loads i recieve error:

TypeError: Cannot read property 'request' of undefined at eval (http://localhost:5555/node_modules/ng2-resource-rest/index.js:305:44)

As i understood, angular missing Http in Resource constructor.
According to this i've added to my QuestionResource own constructor to pass Http to Resouce constructor (just for test).

constructor(@Inject(Http) protected http: Http) {
        super.constructor(this.http);
    }

After this, request loaded as it used to. But i've got another errors in Resource...


Help me please. Have no opinion what to fix in my code.

Webpack warning

Hi @troyanskiy,

after upgrading to 1.5.0 Webpack gives the following warning:

WARNING in .//ng2-resource-rest/bundles/ng2-resource-rest.js
Critical dependencies:
1:3743-3750 require function is used in a way in which dependencies cannot be statically extracted
1:3789-3796 require function is used in a way in which dependencies cannot be statically extracted
@ ./
/ng2-resource-rest/bundles/ng2-resource-rest.js 1:3743-3750 1:3789-3796

Angular 2.0.0 Support

Ionic just released Ionic 2 RC with Angular 2.0.0 underneath. From the Angular change log (https://github.com/angular/angular/blob/master/CHANGELOG.md), it doesn't look like there were many breaking changes from Angular 2 RC 6 to 2.0.0, so I'm getting ready to try updating. Do you know if ng2-resource-rest works with Angular 2.0 Final? I can try and share my findings if that would be helpful. Thanks

Unexpected token export

Actually subj. Uncaught SyntaxError: Unexpected token export error happens when I use the latest version of the library. If I use ~1.3.0 it does not happen.

What kind of additional input would you need to fix the issue?

/node_modules/ng2-resource-rest/ 403 (Forbidden)

i used [email protected]


system.src.js:1154 GET http://127.0.0.1/node_modules/ng2-resource-rest/ 403 (Forbidden)fetchTextFromURL @ system.src.js:1154(anonymous function) @ system.src.js:1710ZoneAwarePromise @ angular2-polyfills.js:589(anonymous function) @ system.src.js:1709(anonymous function) @ system.src.js:2734(anonymous function) @ system.src.js:3308(anonymous function) @ system.src.js:3575(anonymous function) @ system.src.js:3960(anonymous function) @ system.src.js:4419(anonymous function) @ system.src.js:4671(anonymous function) @ system.src.js:406ZoneDelegate.invoke @ angular2-polyfills.js:332Zone.run @ angular2-polyfills.js:227(anonymous function) @ angular2-polyfills.js:576ZoneDelegate.invokeTask @ angular2-polyfills.js:365Zone.runTask @ angular2-polyfills.js:263drainMicroTaskQueue @ angular2-polyfills.js:482ZoneTask.invoke @ angular2-polyfills.js:434
angular2-polyfills.js:332 Error: Error: XHR error (403 Forbidden) loading http://127.0.0.1/node_modules/ng2-resource-rest(…)ZoneDelegate.invoke @ angular2-polyfills.js:332Zone.run @ angular2-polyfills.js:227(anonymous function) @ angular2-polyfills.js:576ZoneDelegate.invokeTask @ angular2-polyfills.js:365Zone.runTask @ angular2-polyfills.js:263drainMicroTaskQueue @ angular2-polyfills.js:482ZoneTask.invoke @ angular2-polyfills.js:434


[email protected] /code/web/my/ngApp
├── @angular2-material/[email protected]
├── @angular2-material/[email protected]
├── @angular2-material/[email protected]
├── @angular2-material/[email protected]
├── @angular2-material/[email protected]
├── @angular2-material/[email protected]
├── @angular2-material/[email protected]
├── @angular2-material/[email protected]
├── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
├── [email protected] extraneous
├── [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ └─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── UNMET OPTIONAL DEPENDENCY fsevents@^1.0.0
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ └─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ ├── [email protected]
│ │ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ │ └── [email protected]
│ │ │ │ │ │ ├── [email protected]
│ │ │ │ │ │ └── [email protected]
│ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ └── [email protected]
│ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ ├── [email protected]
│ │ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ │ └── [email protected]
│ │ │ │ │ │ └── [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ └── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├─┬ [email protected]
│ └── [email protected]
├── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ └─┬ [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ └── [email protected]
└── [email protected]

npm ERR! extraneous: [email protected] /code/web/my/ngApp/node_modules/es6-promise


my js config:

<script> System.config({ map: { "ng2-material":"node_modules/ng2-material", "ng2-resource-rest":"node_modules/ng2-resource-rest", }, ``` packages: { app: { format: 'register', defaultExtension: 'js' }, 'ng2-material': { defaultExtension: 'js' }, 'ng2-resource-rest': { defaultExtension: 'js' } } }); System.import('app/main') .then(null, console.error.bind(console)); ``` </script>

Set URL Dynamically from another service

Great library! This might be more of a Readme or user issue as I couldn't figure it out - is there any way to dynamically set the URL (e.g. inject it from another service) rather than hard-coding it into the ResourceParams decorator? Thanks in advance

this.userRes.get() send two request

 this.userRes.get({firstName: 'John'})
                .$observable
                .subscribe(
                    res => console.log(res),
                    err => console.log('Err', err)
                );

get,query,save,update,remove

could you fix it ,Let it just send a request ?

custom methods TypeError: Cannot read property '$observable' of null

//login.res

import {Resource, ResourceParams, ResourceAction, ResourceResult} from "ng2-resource-rest";
import {Component,Injectable} from '@angular/core';
import { Cookie } from 'ng2-cookies/ng2-cookies';
let csrftoken = Cookie.get('csrftoken');

// Make it Injectable
@Injectable()
// Decorate the your resource class
@ResourceParams({ 
    url: '',
    headers:{
        "X-CSRFToken":csrftoken,
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    },
    // Api path
    path: '/api-auth/login/'
})
export class LoginRes extends Resource {
    login(data:any, callback?:Function): ResourceResult { return null; }
}
  ```

this.Res.login({csrfmiddlewaretoken:'kgEviC68d6OAB23v5fZlu0e1GO5oig7c',next:'/',username:'111111',password:'222222'})
.$observable
.subscribe(
res => console.log(res),
err => console.log('Err', err)
);


error info:

browser_adapter.ts:78 ORIGINAL EXCEPTION: TypeError: Cannot read property '$observable' of nullBrowserDomAdapter.logError @ browser_adapter.ts:78ExceptionHandler.call @ exception_handler.ts:65(anonymous function) @ application_ref.ts:304schedulerFn @ async.ts:131SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.next @ Subscriber.ts:192Subscriber._next @ Subscriber.ts:133Subscriber.next @ Subscriber.ts:93Subject._finalNext @ Subject.ts:154Subject._next @ Subject.ts:144Subject.next @ Subject.ts:90EventEmitter.emit @ async.ts:117NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ ng_zone.ts:138NgZoneImpl.inner.inner.fork.onHandleError @ ng_zone_impl.ts:90ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233NgZoneImpl.runInnerGuarded @ ng_zone_impl.ts:100NgZone.runGuarded @ ng_zone.ts:216outsideHandler @ dom_events.ts:16ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
browser_adapter.ts:78 ORIGINAL STACKTRACE:BrowserDomAdapter.logError @ browser_adapter.ts:78ExceptionHandler.call @ exception_handler.ts:69(anonymous function) @ application_ref.ts:304schedulerFn @ async.ts:131SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.next @ Subscriber.ts:192Subscriber._next @ Subscriber.ts:133Subscriber.next @ Subscriber.ts:93Subject._finalNext @ Subject.ts:154Subject._next @ Subject.ts:144Subject.next @ Subject.ts:90EventEmitter.emit @ async.ts:117NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ ng_zone.ts:138NgZoneImpl.inner.inner.fork.onHandleError @ ng_zone_impl.ts:90ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233NgZoneImpl.runInnerGuarded @ ng_zone_impl.ts:100NgZone.runGuarded @ ng_zone.ts:216outsideHandler @ dom_events.ts:16ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
browser_adapter.ts:78 TypeError: Cannot read property '$observable' of null
at LoginComponent.submitData (login.component.js:76)
at DebugAppView._View_LoginComponent0._handle_click_27_0 (LoginComponent.template.js:646)
at eval (view.ts:374)
at eval (dom_renderer.ts:308)
at eval (dom_events.ts:16)
at ZoneDelegate.invoke (zone.js:323)
at Object.NgZoneImpl.inner.inner.fork.onInvoke (ng_zone_impl.ts:67)
at ZoneDelegate.invoke (zone.js:322)
at Zone.runGuarded (zone.js:230)
at NgZoneImpl.runInnerGuarded (ng_zone_impl.ts:100)BrowserDomAdapter.logError @ browser_adapter.ts:78ExceptionHandler.call @ exception_handler.ts:70(anonymous function) @ application_ref.ts:304schedulerFn @ async.ts:131SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.next @ Subscriber.ts:192Subscriber._next @ Subscriber.ts:133Subscriber.next @ Subscriber.ts:93Subject._finalNext @ Subject.ts:154Subject._next @ Subject.ts:144Subject.next @ Subject.ts:90EventEmitter.emit @ async.ts:117NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ ng_zone.ts:138NgZoneImpl.inner.inner.fork.onHandleError @ ng_zone_impl.ts:90ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233NgZoneImpl.runInnerGuarded @ ng_zone_impl.ts:100NgZone.runGuarded @ ng_zone.ts:216outsideHandler @ dom_events.ts:16ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
browser_adapter.ts:78 ERROR CONTEXT:BrowserDomAdapter.logError @ browser_adapter.ts:78ExceptionHandler.call @ exception_handler.ts:74(anonymous function) @ application_ref.ts:304schedulerFn @ async.ts:131SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.next @ Subscriber.ts:192Subscriber._next @ Subscriber.ts:133Subscriber.next @ Subscriber.ts:93Subject._finalNext @ Subject.ts:154Subject._next @ Subject.ts:144Subject.next @ Subject.ts:90EventEmitter.emit @ async.ts:117NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ ng_zone.ts:138NgZoneImpl.inner.inner.fork.onHandleError @ ng_zone_impl.ts:90ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233NgZoneImpl.runInnerGuarded @ ng_zone_impl.ts:100NgZone.runGuarded @ ng_zone.ts:216outsideHandler @ dom_events.ts:16ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
browser_adapter.ts:78 DebugContext {_view: _View_LoginComponent0, _nodeIndex: 27, _tplRow: 21, _tplCol: 76}BrowserDomAdapter.logError @ browser_adapter.ts:78ExceptionHandler.call @ exception_handler.ts:75(anonymous function) @ application_ref.ts:304schedulerFn @ async.ts:131SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.next @ Subscriber.ts:192Subscriber._next @ Subscriber.ts:133Subscriber.next @ Subscriber.ts:93Subject._finalNext @ Subject.ts:154Subject._next @ Subject.ts:144Subject.next @ Subject.ts:90EventEmitter.emit @ async.ts:117NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ ng_zone.ts:138NgZoneImpl.inner.inner.fork.onHandleError @ ng_zone_impl.ts:90ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233NgZoneImpl.runInnerGuarded @ ng_zone_impl.ts:100NgZone.runGuarded @ ng_zone.ts:216outsideHandler @ dom_events.ts:16ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
zone.js:260 Uncaught EXCEPTION: Error in app/app/login.component.html:21:76
ORIGINAL EXCEPTION: TypeError: Cannot read property '$observable' of null
ORIGINAL STACKTRACE:
TypeError: Cannot read property '$observable' of null
at LoginComponent.submitData (https://127.0.0.1:30004/app/app/login.component.js:76:17)
at DebugAppView._View_LoginComponent0._handle_click_27_0 (LoginComponent.template.js:646:28)
at eval (https://127.0.0.1:30004/node_modules/@angular/core/src/linker/view.js:316:24)
at eval (https://127.0.0.1:30004/node_modules/@angular/platform-browser/src/dom/dom_renderer.js:278:36)
at eval (https://127.0.0.1:30004/node_modules/@angular/platform-browser/src/dom/events/dom_events.js:20:93)
at ZoneDelegate.invoke (https://127.0.0.1:30004/node_modules/zone.js/dist/zone.js:323:29)
at Object.NgZoneImpl.inner.inner.fork.onInvoke (https://127.0.0.1:30004/node_modules/@angular/core/src/zone/ng_zone_impl.js:45:41)
at ZoneDelegate.invoke (https://127.0.0.1:30004/node_modules/zone.js/dist/zone.js:322:35)
at Zone.runGuarded (https://127.0.0.1:30004/node_modules/zone.js/dist/zone.js:230:48)
at NgZoneImpl.runInnerGuarded (https://127.0.0.1:30004/node_modules/@angular/core/src/zone/ng_zone_impl.js:78:78)
ERROR CONTEXT:
[object Object]


error handling in ./resources/UserRes.ts

......
//./resources/UserRes.ts 

export class UserRes extends Resource {   
 //error handling  in there

     get(err){
         if(error.status == 403){
                 alert("please login");
                 this._router.navigate(['Login']);
          } else if(error.status == 404)    {
                 alert("not fund");
                 this._router.navigate(['Index']);
          }

      }
     post(error){
         if(error.status == 403){
                 alert("please login");
                 this._router.navigate(['Login']);
          } 
    }

}

rc6 issue

I'd like to use your module in my app. It seems to be even better than the earlier versions, but I've got stuck at the importing phrase.
Error: Invalid provider for the NgModule 'ResourceModule' - only instances of Provider and Type are allowed, got: [?undefined?]

Could you help me?

Thank you in advance.

How can I send out a array?

Hello,

one of our server's interface need the params that are instance of Array.

However,when I want to send out the data of Array,the resource parse it to a object and then stringify it automatically.

So how can i send out the data as an array?

thanks for your answer!

Ability to call request error callback

Hello! I'm trying to track unsuccessful response code (in my case 401), in order to log out authenticated user. I've tried to specify responseInteceptor as a parameter in ResourceAction with interface defined in Interfaces.ts, but in interceptor I'm only able to interact with Response object which, of cource, doen't have any of response params.
How do can I define interceptor that will have got Response object?
Thx.

Generating resources

Hello,

We have a plenty of resources (e.g. 30), which are different only by name and could do various things and have different.

Previously (in angular 1) we have used ngResource:
https://github.com/angular/angular.js/blob/master/src/ngResource/resource.js
which had CRUD methods and abstract resources.

$resource(path, id, etc) did everything (we could parameterize with uri).

With ng2-resource-rest can I create such abstract method?

E.g.

class AbstractResource extend Resource{
  path: string;
  constructor(config:GlobalConfig, method:string)
    this.path = config.makePath(method)
  }
}

Alternatively, I could create a list of

@Injectable()
@ResourceParams({
  url: makePath(MyRes1)
})
export class MyRes1 extends ResourceCRUD<any, any, any> {}

@Injectable()
@ResourceParams({
  url: makePath(MyRes2)
})
export class MyRes2 extends ResourceCRUD<any, any, any> {}

But, the problem is that the path is prefixed (I will know it only at runtime).

PS: I do not want to lose benefits of aot, thus do it without dynamic compiling.

Thanks!

URL with multiple ids

Hello!

In my application I have, sometimes, complexe URL like:

/api/v1/cars/{id}/pieces/{id2}/detail/{id3}

But when I call .get() or .remove() methods I get some warnings like:

Argument of type '{ id: number; id2: number; id3: number; }' is not assignable to parameter of type '{ id: any; }'.

If we take a look at the ResourceCRUD definition, it's understable:

get: ResourceMethod<{
        id: any;
    }, TFull>;

remove: ResourceMethod<{
        id: any;
    }, any>;

It's limited to one id in the URL.

Unless it's on the REST strict definition, maybe this param could be less limited. Am I right?

Regards,

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://127.0.0.1' is therefore not allowed access.

res file

import {Resource, ResourceParams} from "ng2-resource-rest";

import {Injectable} from "@angular/core";


// Make it Injectable
@Injectable()
// Decorate the your resource class
@ResourceParams({
  // Url to api
  url: 'https://query.yahooapis.com',
  headers:{
    // "X-CSRFToken":csrftoken,
    'Access-Control-Allow-Origin' :'*',
    'Access-Control-Allow-Methods':'POST, GET, OPTIONS',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  // Api path
  path: '/v1/public/yql'
})
export class YqlRes extends Resource {

}

ts code:

 getInfo(){
   let tsql='select * from json  where url="http://jsonplaceholder.typicode.com/posts"';
   this.yqlRes.get({q:tsql});

 }

then ' i got an error

XMLHttpRequest cannot load https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20json%20%20where%20url%3D%22http%3A%2F%2Fjsonplaceholder.typicode.com%2Fposts%22&format=json&diagnostics=true&callback=. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://127.0.0.1' is therefore not allowed access.

could you help me?

thank you very much

Error CORS with Safari

Error: Failed to load resource: Request header field Cache-Control is not allowed by Access-Control-Allow-Headers.

With Chrome work fine.

Usability problems

First of all, I like the library. Thank you for you effort!

After some playing I found out some things concerning the usability improvement

1st. I'm used to define the data type inside of resource file to successfully reuse it everywhere.

E.g. wherever I call the resource I use the following:

myResource.read().subscribe(res => res. /* and here it knows what is res */)

What you offer, as I can see, does not really allow that. This is the best I could come to to make it possible

import { Resource, ResourceAction, ResourceParams, ResourceResult } from 'ng2-resource-rest';
import { RequestMethod } from '@angular/http';
import { Observable } from 'rxjs';

@ResourceParams({
  url: '/api/',
  path: 'v1/preview/{id}'
})
export class PreviewResource extends Resource {

  @ResourceAction({ method: RequestMethod.Get })
  private _read(data?: { id: string; }): ResourceResult { return null; }

  public read(id: string): Observable<{ name: string; value: string }> {
    return this._read({ id }).$observable;
  }

}

Would be nice to have something like

import { Resource, ResourceAction, ResourceParams, ResourceResult } from 'ng2-resource-rest';
import { RequestMethod } from '@angular/http';
import { Observable } from 'rxjs';

interface onSuccess {  ... }

interface onError { ... }

@ResourceParams({
  url: '/api/',
  path: 'v1/preview/{id}'
})
export class PreviewResource extends Resource {

  @ResourceAction({ method: RequestMethod.Get })
  public read(data: { id: string }): ResourceResult<OnSuccess, OnError> {
    return this._read({ id }).$observable;
  }

}

This allows to use the resource way smoother, encapsulates the logic and response format in the place where it should be and finally uses the TypeScript with its full power.

Also you would get rid of the array problem inside of the result, because it could be simply the part of generics: <OnSuccess[], OnError>

2nd. Another thing I cannot understand is why instead of returning a raw Observable the object is returned. Observable gives enough flexibility to check whether it is resolved or not. Is there a way to return the observable directly?

3rd. Can we specify the url ResourceParamsBase property in a global way for the whole application (e.g. in a bootstrap file)? Maybe it is not that useful for every project but still would be nice to have

Question about getHeaders

Hello.

I'm trying to implement API with OAuth. i made a service to handle that and works propertly but i want to used it in the resources. I created a OAuthGuardResource to extends of it all other Resources

@ResourceParams({
    url: BASE_API,
    add2Provides: false
})
export class OAuthGuardResource extends Resource {

    getHeaders() {
        let headers = super.getHeaders();
        let auth = OAuthService.instance;
        if(auth.hasAuthorization()){
            headers.Authorization = auth.getHeaderAuthorization();
        } else if(auth.hasAuthorizationRefresh()) {
            return auth.refreshToken()
                .toPromise()
                .then(
                    (res: Response) => {
                        auth.saveTokens(res.json());
                        headers.Authorization = auth.getHeaderAuthorization();
                        return headers;
                    }
                ).catch((error: any) => {
                    console.error("Catch OAuthGuardResource Error:",error);
                    return headers;
                });
        } else {
            location.href = BASE+"/login";
        }
        return headers;
    }
}

and i have the UserResource

@ResourceParams({
    url:BASE_API+"/users"
})
export class UserResource extends OAuthGuardResource {
    @ResourceAction({
        isArray: false
    })
    query: ResourceMethod<IUserQueryInput, IUserShort[]>;
}

The thing is when the resource make the query, the method getHeaders is called two times.
I dont know if I'm doing something wrong.

Thanks

Module or jsnext:main in package.json

Since this is a Typescript app, can you distribute es5 code (es5 target) with es2015 modules in addition to the commonjs modules you distribute?

Set the moduleResolution to node as well to make everything work well in the tsconfig.json.

jsnext:main and module are the fields that point to the entrypoint for the es5 code with es2015 modules. Angular uses module and it seems most bundlers look for module, then jsnext:main, then main in that order.

Thanks,
Dan

'data' parameter persisting between requests

I have two components using the same Resource subclass, but they're making requests with different parameters. The trouble is that parameters set using one persist when they're not included in the other. I've even tried adding the resource to the components' providers array so that each one gets its own instance, but that doesn't seem to work.

For example if I make a request in one component:

constructor(private resource: ResourceSubclass) {}
...
this.items = this.resource.query({ param1: 'foo' });

The query string will be ?param1=foo, which is expected.

Then, if I switch routes and another component makes a request using the same Resource type:

constructor(private resource: ResourceSubclass) {}
...
this.items = this.resource.query({ param2: 'bar' });

The query string will be ?param2=bar&param1=foo, which is unexpected. Each request should have its own parameters created based on the data passed in through the method and the data parameter in the ResourceParams decorator. Parameters shouldn't persist between calls unless they're in the decorator.

I tried to dig through the source but I can't find what's causing this behavior.

v1.0.1 Can't override ResourceCRUD ResourceActions

I'm having trouble overriding actions from the ResourceCRUD class.

For example, in one class I'm doing a sort on the results of query() before it gets passed to the caller. I can't figure out how I would do that using a ResourceCRUD subclass without wrapping the whole thing in a service.

Import only the required operators from Rx

Import only the required operators from Rx. I am not sure why the full import in frowned upon. But from recent communications from different forums it looks like the recommended approach is to import what is required.

Unexpected value 'AppComponent' declared by the module 'AppModule'

When I add ResourceModule.forRoot() to AppModule-imports I get that error.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { ResourceModule } from 'ng2-resource-rest';

import { AppComponent } from './app.component';
import { APP_ROUTING } from './app.routing';

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ResourceModule.forRoot(),
APP_ROUTING
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}

how to get current request url

hi dear troyanskiy;

i hope i can use this.userRes.geCurrentUrl() get current request url

i hope i can get url parameters,like this:

let url = "http://restframework.herokuapp.com/snippets/?page=3";

let page=getUrlPar(url,"page");
console.log(page) ; // print 3

getUrlPar(local_url,par){
        local_url = (local_url==null)?"":local_url
        let get = local_url.indexOf(par+"=");
        if (get == -1){
            return 1;
        };
        let get_par = local_url.slice(par.length+get+1);
        let nextPar = get_par.indexOf("&");
        if (nextPar != -1){
            get_par = get_par.slice(0,nextPar);
        };
        return get_par;
    }

request url like:

http://restframework.herokuapp.com/snippets/?page=3

i need display current page 3 in my website page

server restful i use http://www.django-rest-framework.org/

servers return json like this http://restframework.herokuapp.com/snippets/?page=3

i need get url parameters page=3 ,

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.