ghidoz / angular2-jsonapi Goto Github PK
View Code? Open in Web Editor NEWA lightweight Angular 2 adapter for JSON API
A lightweight Angular 2 adapter for JSON API
Hello
First of all - good job with this lib.
I have an change request/question.
In our software we want the jsonapi resource Type in singular and the url-paths in plural.
Unfortunately in your lib is the method "buildUrl" in "json-api-datastore.service.ts" private and i am not allow to overwrite it.
My objective was to insert a new variable "path" in JsonApiModelConfig and use this instead in buildUrl.
I've recently pulled your package from npm as a dependency of another project but it seems that the JsonApiDatastoreConfig decorator js and type definition files are missing.
It works if I npm link the cloned repo so could it be that the files didn't make it in the last npm publish ?
Thanks for the project by the way ๐
I have two models with OneToMany relationship:
@JsonApiModelConfig({
type: 'posts'
})
export class Post extends JsonApiModel {
@Attribute()
title: string;
@HasMany()
comments: Comment[];
}
@JsonApiModelConfig({
type: 'comments'
})
export class Comment extends JsonApiModel {
@Attribute()
title: string;
@BelongsTo()
post: Post;
}
I'm getting one Comment and I update the Post it's belonging to:
this.datastore.findRecord(Comment, '1').subscribe(
(comment: Comment) => {
comment.post = anotherExistingPost;
comment.save().subscribe();
}
);
When I save, the Post my Comment is belonging to is not updated.
Actually my request that is being sent to the server doesn't contain anything to update:
{
"data": {
"type": "comments",
"id": "1",
"attributes": {
"id": "1"
}
}
}
For what I can see in the Library code, the save method is only taking in consideration the properties with @Attribute() decoration.
Unfortunately, my post property of Comment has a @BelongsTo() decoration.
JsonApiModel.prototype.save = function (params, headers) {
var attributesMetadata = Reflect.getMetadata('Attribute', this);
return this._datastore.saveRecord(attributesMetadata, this, params, headers);
};
Then what should be done so that I can update the Post my Comment is belonging to ?
Hi,
I created a Datastore service, and updated a model extending JsonApiModel, as described in the doc.
Now, I don't know how to make the model works in a basic two-way databinding form.
In my component :
export class CreateNoteComponent {
note: Note = new Note();
constructor() { }
onSubmit() {
console.log(this.note);
}
}
My Note model :
@JsonApiModelConfig({
type: 'notes'
})
export class Note extends JsonApiModel {
@Attribute()
title: string;
@Attribute()
content: string;
/** Removed this constructor, as it enters in conflict with the properties declared with @Attributes */
/** constructor (
public title: string,
public content: string
) { } */
}
My view :
<input type="text" name="title" [(ngModel)]="note.title" />
<input type="text" name="content" [(ngModel)]="note.content" />
<button type="submit" (click)="onSubmit()">Submit</button>
{{ JSON.stringify(claimFile) }}
Before I change my model and make it inherit from JsonApiModel, everything worked fine. Each change I typed in the inputs was reflected in the model and displayed in the debug string interpolation.
Now Typescript gives me this error :
create-note.component.ts
(11,28): error TS2346: Supplied parameters do not match any signature of call target.
It comes from the note: Note = new Note()
line.
Seems normal as the JsonApiModel classes has its own constructor signature...
So my questions are :
this.datastore.createRecord(Post, {
title: 'My post',
content: 'My content'
});
I'd like to pass my model as the second argument and not have to explicitely describe each values (especially in a Service). How can I make it ?
Thx a lot for your help
Hi there,
As you now multi inheritance is not allowed in Javascript . So if we have a class which is extending an abstract class , we can not inherit from JsonApiModel anymore .
A sample is here :
export class Market extends ReferenceDate{
id: string;
name: string;
}
if I change the abstract class like this:
export abstract class ReferenceData extends JsonApiModel {
}
then I can not create any new instance of market in this way:
var market= new Market();
I will have syntax error because it needs datastore: JsonApiDatastore, data: any
Hi, I need to know how this library works with same data. For example: When I call
this.datastore.findRecord(Post, '1').subscribe(
(post: Post) => console.log(post)
);
twice. Will post
be the same instance?
What work is involved with removing the strict dependency on the @angular/http version? We're inconveniently locked into v2.0.0 at the moment.
Could the dependency be a more permissive peerDependency instead and allow the project to define the version?
when adding the component to the @ngModules you get an error when opening the page
Error: patchProperty/desc.set/wrapFn@http://localhost:3000/node_modules/zone.js/dist/zone.js:794:27
Zone</ZoneDelegate</ZoneDelegate.prototype.invokeTask@http://localhost:3000/node_modules/zone.js/dist/zone.js:365:24
Zone</Zone</Zone.prototype.runTask@http://localhost:3000/node_modules/zone.js/dist/zone.js:265:29
ZoneTask/this.invoke@http://localhost:3000/node_modules/zone.js/dist/zone.js:433:29
Error loading http://localhost:3000/angular2-jsonapi as "angular2-jsonapi" from http://localhost:3000/app/app.module.js
after running npm start
Where can I find information regarding how to handle subscribes.
Previously when using the http object, I can convert the observable into a promise and then pass that back to controller to manage the behavior of the app - for cases with success or failure.
How do I accomplish the same with the subscribe() function?
Many thanks in advance...
Angular2-jsonapi only supports numbers for resource identifier (id). Ex:
findRecord(type: { new (data: any): JsonApiModel; }, id: number, params?: any, headers?: Headers): Observable<JsonApiModel>;
It's not compatible with Uuid for example.
The JSON API specification doesn't specify that identifiers have to be number.
Therefore, can we allow the identifier to be a string as well ?
Hi, I'm use [email protected]
Ionic Framework Version: 2.0.0-rc.0
Ionic CLI Version: 2.1.0
Ionic App Lib Version: 2.1.0-beta.1
OS: Mac OS X El Capitan
Node Version: v6.7.0
and have error
[15:13:13] bundle dev failed: Module /Users/ivan/github/Mush/node_modules/angular2-jsonapi/dist/index.js does not export JsonApiDatastoreConfig (imported by /Users/ivan/github/Mush/src/services/datastore.ts)
[15:13:13] Error: Module /Users/ivan/github/Mush/node_modules/angular2-jsonapi/dist/index.js does not export JsonApiDatastoreConfig (imported by /Users/ivan/github/Mush/src/services/datastore.ts)
at Module.trace (/Users/ivan/github/Mush/node_modules/rollup/dist/rollup.js:7706:29)
at ModuleScope.findDeclaration (/Users/ivan/github/Mush/node_modules/rollup/dist/rollup.js:7329:22)
at Scope.findDeclaration (/Users/ivan/github/Mush/node_modules/rollup/dist/rollup.js:5349:39)
at CallExpression.bind (/Users/ivan/github/Mush/node_modules/rollup/dist/rollup.js:5834:28)
at /Users/ivan/github/Mush/node_modules/rollup/dist/rollup.js:5149:50
at ArrayExpression.eachChild (/Users/ivan/github/Mush/node_modules/rollup/dist/rollup.js:5163:19)
at ArrayExpression.bind (/Users/ivan/github/Mush/node_modules/rollup/dist/rollup.js:5149:7)
at /Users/ivan/github/Mush/node_modules/rollup/dist/rollup.js:5149:50
at CallExpression.eachChild (/Users/ivan/github/Mush/node_modules/rollup/dist/rollup.js:5163:19)
at CallExpression.bind (/Users/ivan/github/Mush/node_modules/rollup/dist/rollup.js:5149:7)
I've made some adjustments to json-api.model.js to make it more robust..
"use strict";
var _ = require('underscore');
require('reflect-metadata');
var JsonApiModel = (function () {
function JsonApiModel(data) {
if (data) {
this.id = data.id;
_.extend(this, data.attributes);
}
}
JsonApiModel.prototype.syncRelationships = function (data, included, level, datastore) {
if (data) {
this.parseHasMany(data, included, level, datastore);
this.parseBelongsTo(data, included, level, datastore);
}
};
JsonApiModel.prototype.parseHasMany = function (data, included, level, datastore) {
var hasMany = Reflect.getMetadata('HasMany', this);
if (hasMany) {
for (var _i = 0, hasMany_1 = hasMany; _i < hasMany_1.length; _i++) {
var metadata = hasMany_1[_i];
if (data.relationships[metadata.relationship] && data.relationships[metadata.relationship].data && data.relationships[metadata.relationship].data.length > 0) {
var typeName = data.relationships[metadata.relationship].data[0].type;
var objectType = Reflect.getMetadata('JsonApiDatastoreConfig', datastore.constructor).models[typeName];
this[metadata.propertyName] = this.getHasManyRelationship(objectType, data, included, metadata.relationship, typeName, level, datastore);
}
}
}
};
JsonApiModel.prototype.parseBelongsTo = function (data, included, level, datastore) {
var belongsTo = Reflect.getMetadata('BelongsTo', this);
if (belongsTo) {
for (var _i = 0, belongsTo_1 = belongsTo; _i < belongsTo_1.length; _i++) {
var metadata = belongsTo_1[_i];
if (data.relationships[metadata.relationship] && data.relationships[metadata.relationship].data) {
var typeName = data.relationships[metadata.relationship].data.type;
var objectType = Reflect.getMetadata('JsonApiDatastoreConfig', datastore.constructor).models[typeName];
this[metadata.propertyName] = this.getBelongsToRelationship(objectType, data, included, metadata.relationship, typeName, level, datastore);
}
}
}
};
JsonApiModel.prototype.getHasManyRelationship = function (objectType, data, included, relationship, typeName, level, datastore) {
var relationshipList = [];
data.relationships[relationship].data.forEach(function (item) {
var relationshipData = _.findWhere(included, { id: item.id, type: typeName });
if( relationshipData ) {
var newObject = new objectType(relationshipData);
if (relationshipData.relationships && level <= 1) {
newObject.syncRelationships(relationshipData, included, ++level, datastore);
}
relationshipList.push(newObject);
}
});
return relationshipList;
};
JsonApiModel.prototype.getBelongsToRelationship = function (objectType, data, included, relationship, typeName, level, datastore) {
var id = data.relationships[relationship].data.id;
var relationshipData = _.findWhere(included, { id: id, type: typeName });
if(relationshipData) {
var newObject = new objectType(relationshipData);
if (relationshipData.relationships && level <= 1) {
newObject.syncRelationships(relationshipData, included, ++level, datastore);
}
return newObject;
}
};
return JsonApiModel;
}());
exports.JsonApiModel = JsonApiModel;
//# sourceMappingURL=json-api.model.js.map
After upgrading to v3.2, I've got this error message :
client?8fb9:75 ./client/app/app.module.ts (5,31): error TS2307: Cannot find module 'angular2-jsonapi'.
compiler.umd.js?9df7:13996 Uncaught Error: Unexpected value 'JsonApiModule' imported by the module 'AppModule'
I tried to change the position of the import at the top of my app.module.ts, and in the imports[] of my ngModule. No success.
Also tried the fix proposed in #13 and related issues :
module.exports = { resolve: { modules: [ path.join(__dirname, "node_modules") ] } };
Doesn't work either.
Note that the "Unexpected value" displays only in Chrome console, not in my build process.
I use Webpack 1.13.2, but not angular-cli, my project boilerplate is created from scratch.
Thx for your help.
Running under Angular 2 release and when adding JsonApiModule to the imports in app.module.ts I get the following error in the browser:
zone.js:129 Uncaught Error: Unexpected value 'NgaModule' imported by the module 'AppModule'
It seems that after I add JsonApiModule to the app imports it invalidates other imports, not sure if this is an issue with this module or the other but I don't have the issue unless I add JsonApiModule to the app imports
When I use findRecord with an HasMany relationship, I get the following error:
The request is properly sent and the json response is correct.
The issue happens during the parsing of the results at this step: parseHasMany.
For some reasons, objectType is undefined after this line:
var objectType = Reflect.getMetadata('JsonApiDatastoreConfig', datastore.constructor).models[typeName];
This is what I have in my Datastore:
import { Injectable } from '@angular/core';
import { JsonApiDatastoreConfig, JsonApiDatastore } from 'angular2-jsonapi';
import { Country, Brand, Model } from "../";
@Injectable()
@JsonApiDatastoreConfig({
baseUrl: 'http://www.example.com/api/',
models: {
brands: Brand,
models: Model,
countries: Country
}
})
export class Datastore extends JsonApiDatastore { }
And this is what I get when I print Reflect.getMetadata('JsonApiDatastoreConfig', datastore.constructor)
in the console:
I precise that:
Any idea ?
when calling the save() method on the Model. I get an JSON.parse EXCEPTION error.
after some debugging I found that the attributesMetadata variable filled in the JsonApiModel.prototype.save function returns an 'undefined' value.
this is the payload send to the api:
"data": {
"type": "organisations",
"id": "1",
"attributes": {}
}
How do I save a HasMany relationship?
It's clear from the readme that I can save a HasOne relationship just by setting the parameter with the object like
{post: Post}
but that doesn't seem to work for HasMany relationships when I use something like
{comments: [Comment, Comment, Comment]}
Is this not implemented yet?
If not maybe I can help out (although I've never contributed to a github project before, so I may need some help).
Might be me doing something wrong here.
"relationships": { "control_record": { "data": { "type": "control_records", "id": "1" }, "links": { "self": "\/api\/control_records\/view\/1" } } },
I can see it getting picked up in parseHasMany, however relationship.data.length is undefined
due to it being an array. Sadly as the test suite is broken I'm unable to see if that's a thing in the provided examples.
If I manually make relationship.data into [{type: "control_records", id: "1"}]
then it finds the relationship just fine however.
Hi,
I have a use case where I need to rollback all attributes of a model to their last saved state. In the code of the JsonApiModel I found the method rollbackAttributes()
which I excpected to do the job. But when doing two changes on a model attribute it only rolls back one change and not two changes.
Example:
let test = this.datastoreService.createRecord(Role, {});
test.name = "test";
test.save();
console.log(test.name); // prints "test"
test.name = "test2";
test.name = "test22";
test.rollbackAttributes();
console.log(test.name); //prints "test2" but I expected it to print "test"
Is this a bug or expected behaviour? If it's a bug I would like to propose a fix in the saveAnnotations()
method of the Attribute decorator and make a pull request.
Hi @ghidoz,
Do you have a detailed roadmap for this project?
I really like your idea about using decorators. It's very much like the Hibernate or Doctrine ORM. But currently this library missing several important features and couldn't be used in real products.
At work we started a long-term project that have JSON API backend and currently looking for library that allow us consume this backend in Angular 2 apps. I studied several existing libraries and found that your library most in line with our vision of how client-side should interact with JSON API backend.
I would like to help you improve this library and make it useful for real products.
I'm trying to consume some JSON with angular2-jsonapi. The JSON has a relationship between Building and Room. I get a uber ambigious error coming back:
json-api-datastore.service.ts:158 Server errorJsonApiDatastore.handleError @ json-api-datastore.service.ts:158(anonymous function) @ json-api-datastore.service.ts:35CatchSubscriber.error @ catch.ts:58MapSubscriber._next @ map.ts:81Subscriber.next @ Subscriber.ts:95onLoad @ http.umd.js:1230ZoneDelegate.invokeTask @ zone.js:236onInvokeTask @ core.umd.js:6149ZoneDelegate.invokeTask @ zone.js:235Zone.runTask @ zone.js:136ZoneTask.invoke @ zone.js:304
Can you tell me what I'm doing wrong? Thanks in advance!
My call goes something like this
this.datastore.findRecord(Building, building_id, {
include: 'rooms'
}, this.gserv.getHeadersAPI()).subscribe(
(building: Building) =>{
},
(e) =>{
}
);
My JSONAPIMODELS are defined as following..
import { JsonApiModelConfig, JsonApiModel, Attribute, HasMany, BelongsTo } from 'angular2-jsonapi';
@JsonApiModelConfig({
type: 'buildings'
})
export class Building extends JsonApiModel {
@Attribute()
id : string;
@Attribute()
name : string;
@Attribute()
address_1 : string;
@Attribute()
address_2 : string;
@Attribute()
address_3 : string;
@Attribute()
town_or_city : string;
@Attribute()
county : string;
@Attribute()
postcode : string;
@Attribute()
country : string;
@Attribute()
description : string;
@HasMany()
rooms : Room[];
}
@JsonApiModelConfig({
type: 'rooms'
})
export class Room extends JsonApiModel {
@Attribute()
id : string;
@Attribute()
type_of_room: string;
@Attribute()
status: string;
@Attribute()
notes: string;
@BelongsTo()
building: Building;
}
The JSON being return from the API service is as follows...
{
"data": {
"id": "14",
"type": "buildings",
"attributes": {
"name": "Rodolfo Beahan",
"address_1": "8545 Leffler Union",
"address_2": "Suite 742",
"address_3": "",
"town_or_city": "Wardland",
"county": "Wisconsin",
"postcode": "40461",
"country": "Solomon Islands",
"description": "MyText"
},
"relationships": {
"rooms": {
"data": [
{
"id": "107",
"type": "rooms"
},
{
"id": "108",
"type": "rooms"
}
]
}
}
},
"included": [
{
"id": "107",
"type": "rooms",
"attributes": {
"name": "",
"type_of_room": "Single",
"status": "OPEN",
"notes": ""
},
"relationships": {
"building": {
"data": {
"id": "14",
"type": "buildings"
}
}
}
},
{
"id": "108",
"type": "rooms",
"attributes": {
"name": "",
"type_of_room": "Double",
"status": "OPEN",
"notes": ""
},
"relationships": {
"building": {
"data": {
"id": "14",
"type": "buildings"
}
}
}
}
]
}
In current implementation data models highly coupled with data storage. I think it will be better if we will use POJO augmented with decorators for data models. I.e. all methods that change data in underlying storage (currently, save()
) should be moved from JsonApiModel
to JsonApiDataStore
.
Typical interaction with data storage can look like:
// create record
let author = new AuthorModel();
storage.saveRecord(author);
// updating record
storage.findRecord(BookModel, '1').subscribe(
(book) => {
book.title = "New title";
storage.saveRecord(book);
}
);
// deleting record
storage.findRecord(BookModel, '1').subscribe(
(book) => storage.deleteRecord(book);
);
This approach have following advantages:
JsonApiDataStorage
. It can be easily created and tested.storage.beginTransaction();
/* posts: BlogPostModel[] */
posts.forEach((post) => {
post.published = true;
storage.saveRecord(post); // request will be delayed because of transaction
});
storage.commit(); // update all posts in underlying storage using single request
Aloha,
I'm receiving the following console error when attempting to make a request for data using a model with a @BelongsTo relationship.
parseBelongsTo - Model type for relationship customers not found.
component.ts
this.datastore.query( Receivable, {
include: 'customers' // include customers with receivables
}).subscribe( ( receivables: Receivable[] ) => {
console.log(receivables)
});
datastore.ts
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import {
JsonApiDatastoreConfig,
JsonApiDatastore,
JsonApiModelConfig,
JsonApiModel,
Attribute,
HasMany,
BelongsTo
} from 'angular2-jsonapi';
import { environment } from '../../environments/environment';
/**
* JSON API Service Configuration Decorator
*/
@Injectable()
@JsonApiDatastoreConfig({
baseUrl: environment.hostname + '/api/v1/',
models: {
customers: Customer,
receivables: Receivable
}
})
export class DatastoreService extends JsonApiDatastore {
constructor(http: Http) {
super(http);
}
}
/**
* Customers model
* @desc JSON API Model Configuration
*/
@JsonApiModelConfig({
type: 'customers'
})
export class Customer extends JsonApiModel {
@Attribute()
name: string;
@Attribute()
city: string;
@Attribute()
phone: string;
@Attribute()
state: string;
@Attribute()
street: string;
@Attribute()
zip: string;
@HasMany()
receivables: Receivable[];
}
/**
* Receivables model
* @desc JSON API Model Configuration
*/
@JsonApiModelConfig({
type: 'receivables'
})
export class Receivable extends JsonApiModel {
@Attribute()
invoice_date: Date;
@Attribute()
invoice_due_date: Date;
@Attribute()
invoice_amount_due: number;
@Attribute()
owner_id: string;
@Attribute()
supplier_id: string;
@Attribute()
customer_id: string;
@BelongsTo()
customer: Customer;
}
JSON from server
{
"data": [
{
"attributes": {
"created_at": "2017-01-24T02:05:47.259Z",
"customer_id": 2470,
"invoice_amount_due": "93.356",
"invoice_date": "2017-01-19",
"invoice_due_date": "2017-04-07",
"owner_id": 7476,
"supplier_id": 7477,
"updated_at": "2017-01-24T02:05:47.259Z"
},
"id": "3839",
"relationships": {
"customer": {
"data": {
"id": "2470",
"type": "customers"
}
}
},
"type": "receivables"
}
],
"included": [
{
"attributes": {
"city": "South Coltenhaven",
"name": "Koch and Sons",
"phone": "1-410-235-4477 x230",
"state": "AK",
"street": "3563 Louisa Walk",
"zip": "90083-5352"
},
"id": "2470",
"type": "customers"
}
]
}
Any help here would be appreciated.
Mahalo!
Typescript 2.0 now supports getting type definitions directly from npm.
The project I am working on no longer has typings as a dependency, installing this library causes an error.
Please see the pull request below for changes.
#18
Hi,
first thx for this library - sounds very promising. Unfortunately I can't get it to run as I get lots of errors after installing. As I'm fairly new to all this npm and JS stuff (only did python and jquery until a few months ago shame ) I don't know what to do with this error - maybe it's an easy fix. Googling didn't help me, so I hope you guys maybe have an idea.
The problem:
I bootstrapped an ng project with angular-cli's ng new
( https://cli.angular.io/ ) this is working perfectly and ng serve
runs without problems and gives me the hello world page in the browser. Now I try to install angular2-jsonapi with npm install angular2-jsonapi --save
and already get some "UNMET PEER DEPENDENCY" error thing I don't know what to do with.
asmaps@naos ~/git/letsmeet-angular2-ui (master*) $ npm install angular2-jsonapi --save
[email protected] /home/asmaps/git/letsmeet-angular2-ui
โโโ UNMET PEER DEPENDENCY @angular/[email protected]
โโโ UNMET PEER DEPENDENCY @angular/[email protected]
โโโ UNMET PEER DEPENDENCY @angular/[email protected]
โโโ UNMET PEER DEPENDENCY @angular/[email protected]
โโโฌ [email protected]
โโโ @angular/[email protected]
โโโ @angular/[email protected]
โโโ @angular/[email protected]
โโโ @angular/[email protected]
โโโ @angular/[email protected]
โโโ @types/[email protected]
โโโ @types/[email protected]
โโโ @types/[email protected]
โโโ [email protected]
โโโ [email protected]
npm WARN optional Skipping failed optional dependency /chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: [email protected]
npm WARN @angular/[email protected] requires a peer of @angular/[email protected] but none was installed.
npm WARN @angular/[email protected] requires a peer of @angular/[email protected] but none was installed.
npm WARN @angular/[email protected] requires a peer of @angular/[email protected] but none was installed.
npm WARN @angular/[email protected] requires a peer of @angular/[email protected] but none was installed.
npm WARN @angular/[email protected] requires a peer of @angular/[email protected] but none was installed.
My resulting package.json
:
{
"name": "letsmeet-angular2-ui",
"version": "0.0.0",
"license": "MIT",
"angular-cli": {},
"scripts": {
"start": "ng serve",
"lint": "tslint \"src/**/*.ts\"",
"test": "ng test",
"pree2e": "webdriver-manager update",
"e2e": "protractor"
},
"private": true,
"dependencies": {
"@angular/common": "~2.0.0",
"@angular/compiler": "~2.0.0",
"@angular/core": "~2.0.0",
"@angular/forms": "~2.0.0",
"@angular/http": "~2.0.0",
"@angular/platform-browser": "~2.0.0",
"@angular/platform-browser-dynamic": "~2.0.0",
"@angular/router": "~3.0.0",
"angular2-jsonapi": "^3.2.0",
"core-js": "^2.4.1",
"rxjs": "5.0.0-beta.12",
"ts-helpers": "^1.1.1",
"zone.js": "^0.6.23"
},
"devDependencies": {
"@types/jasmine": "^2.2.30",
"@types/node": "^6.0.42",
"angular-cli": "1.0.0-beta.17",
"codelyzer": "~0.0.26",
"jasmine-core": "2.4.1",
"jasmine-spec-reporter": "2.5.0",
"karma": "1.2.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-jasmine": "^1.0.2",
"karma-remap-istanbul": "^0.2.1",
"protractor": "4.0.9",
"ts-node": "1.2.1",
"tslint": "3.13.0",
"typescript": "2.0.2"
}
}
when I now try to run ng serve
I get lots of errors, also when I try to add import { JsonApiModule } from 'angular2-jsonapi';
to my AppModule I only get an import error (not found).
asmaps@naos ~/git/letsmeet-angular2-ui (master*) $ ng serve
Could not start watchman; falling back to NodeWatcher for file system events.
Visit http://ember-cli.com/user-guide/#watchman for more info.
** NG Live Development Server is running on http://localhost:4200. **
4892ms building modules
13ms sealing
0ms optimizing
0ms basic module optimization
69ms module optimization
1ms advanced module optimization
7ms basic chunk optimization
0ms chunk optimization
1ms advanced chunk optimization
0ms module and chunk tree optimization
84ms module reviving
1ms module order optimization
3ms module id optimization
3ms chunk reviving
0ms chunk order optimization
9ms chunk id optimization
49ms hashing
0ms module assets processing
99ms chunk assets processing
2ms additional chunk assets processing
0ms recording
0ms additional asset processing
1304ms chunk asset optimization
1442ms asset optimization
33ms emitting
Hash: 6901610443f768eb66c3
Version: webpack 2.1.0-beta.25
Time: 8031ms
Asset Size Chunks Chunk Names
main.bundle.js 2.78 MB 0, 2 [emitted] main
styles.bundle.js 10.2 kB 1, 2 [emitted] styles
inline.js 5.53 kB 2 [emitted] inline
main.map 2.86 MB 0, 2 [emitted] main
styles.map 14.1 kB 1, 2 [emitted] styles
inline.map 5.59 kB 2 [emitted] inline
index.html 481 bytes [emitted]
assets/.npmignore 0 bytes [emitted]
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:6:13
Duplicate identifier 'PropertyKey'.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:10:4
All declarations of 'value' must have identical modifiers.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:248:4
All declarations of 'EPSILON' must have identical modifiers.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:283:4
All declarations of 'MAX_SAFE_INTEGER' must have identical modifiers.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:290:4
All declarations of 'MIN_SAFE_INTEGER' must have identical modifiers.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:346:4
All declarations of 'flags' must have identical modifiers.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:498:4
All declarations of 'prototype' must have identical modifiers.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:561:4
All declarations of 'size' must have identical modifiers.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:570:4
All declarations of 'prototype' must have identical modifiers.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:581:4
All declarations of 'size' must have identical modifiers.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:591:4
All declarations of 'prototype' must have identical modifiers.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:606:4
All declarations of 'prototype' must have identical modifiers.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/@types/es6-shim/index.d.ts:620:4
All declarations of 'prototype' must have identical modifiers.
ERROR in [default] /home/asmaps/git/letsmeet-angular2-ui/node_modules/typescript/lib/lib.es2015.core.d.ts:17:13
Duplicate identifier 'PropertyKey'.
Child html-webpack-plugin for "index.html":
Asset Size Chunks Chunk Names
index.html 2.81 kB 0
webpack: bundle is now VALID.
Can you point me somewhere how I can fix this?
Thx in advance
PS: Do you have an IRC channel or similar?
npm install angular2-jsonapi --save
[email protected] /Users/stockn/source/Tech4team/aerometrix
โโโ UNMET PEER DEPENDENCY @angular/[email protected]
โโโ UNMET PEER DEPENDENCY @angular/[email protected]
โโโ [email protected]
โโโ UNMET PEER DEPENDENCY [email protected]
npm WARN [email protected] requires a peer of @angular/[email protected] but none was installed.
npm WARN [email protected] requires a peer of @angular/[email protected] but none was installed.
npm WARN [email protected] requires a peer of [email protected] but none was installed.
My cores, directly from angular-cli generator are "@angular/common": "^2.3.1",
"@angular/compiler": "^2.3.1",
"@angular/core": "^2.3.1",
I spent over an hour trying to play with dependencies to get it to work, any help or guidance is appreciated.
Angular 2 uses lodash internally and here we use underscore. This has the possibility for errors as both libraries try to define window._
I have trialled this change locally and it seems to work without issue.
Hi,
I am using your library for loading JSON Spec data and I can't load nested relationship .
here is my class diagram:
class Person{
id:number;
name:string;
@BelongsTo()
car: Car;
}
class Car{
id:number;
@BelongsTo()
market: Market;
}
class Market{
id:nmber
}
when I want to load Persons data I use include:"car.market" and it loads all persons with relation to car but it doesn't load nested relation of car and market
Could you please let me know if there is any solution ?
If more people are getting involved it would be good to add some tests to ensure we don't regress any functionality.
Using the latest angular-cli, after following your instructions I get the following errors:
zone.js:461 Unhandled Promise rejection: Error: XHR error (404 Not Found) loading http://localhost:4200/reflect-metadata
It appears that systemjs is trying to load these via an xhr and obviously failing. It would seem that your projects dependencies would also need to be included in the vendor folder and thus, part of angular-cli-build.js
and system-config.ts
. I'm fairly new to TS so maybe I'm missing a crucial step here?
Hello,
I'm trying to add headers to provide a token access to my API. The guide gives this line :
this.datastore.headers = new Headers({'Authorization': 'Bearer ' + accessToken});
and 2 other examples, but they seem to be on the consumer components side. I'd like to avoid specifying headers it in each of my HTTP calls.
First I tried to add it in a "headers" key within the @JsonApiDatastoreConfig decorator, but didn't work.
Then I tried to put it in my Datastore service, in the constructor :
export class Datastore extends JsonApiDatastore {
constructor(http: Http) {
super(http);
this.headers = new Headers({ 'Authorization': 'Bearer ' + localStorage.getItem('access_token')});
}
}
Now something strange, each time I validate my form and check the headers that are sent to the server, it turns out that the "accept" and "Content-type" keys are repeated.
Example, if I submit my form 3 times, I get on the third call :
accept:application/vnd.api+json,application/vnd.api+json,application/vnd.api+json
authorization:Bearer NDgyZGQ1YTIzMTZiNjg4MzY0ZDVmOTk1NzkyZjZjZGNmZjIyZDZmMDU2YzY0NThmYzc5OGM1ZmE2ZTcxZWE3ZA
content-type:application/vnd.api+json,application/vnd.api+json,application/vnd.api+json
Does it come from the way I add my header ?
Just for information, when I submit a form, server doesn't return a valid response yet (test purpose), so the app is assumed to be crashed.
Thx for your help
During the development and test cycle of an application it's quite normal to have different environments for development and testing purposes. These environments could have different domain names, and or ports associated with the configuration.
Having the baseUrl parameter as part of the DataStore attributes makes this quite difficult to achieve. I've got a workaround for now, but it's not ideal. I have a think into a better solution, any suggestions would be appreciated.
Hi,
I read the discussion about the roadmap in #19 so I'm going to create a new issue to have some space to discuss a topic that needs some more refactoring. I'm currently using this package in a small opensource client. The client makes use of HATEOAS and thus needs support for the top level link
attribute in json:api.
Currently this package only handles the data
attribute. But there is a RFC for ember-data that proposes how to implement support for more general json:api documents. If I got the idea of the RFC adapted to this package right, then you should be able to make a request to the API and get something like a DocumentModel
(instead of a JsonApiModel
) as response. The DocumentModel
gives you access to all the top level attributes of a json:api document using the following getter methods:
data(): JsonApiModel
(existing JsonApiModel)links(): LinksModel
(new model)meta(): MetaModel
(new model)A basic query then would look like this:
this.datastoreService.query(User, {
page: { size: 10, number: 1},
include: 'roles'
}).subscribe(
(document: DocumentModel) => {
// access to the JsonApiModel
this.users = document.data();
// access to the top level links attribute
this.links = document.links();
// access to the json:api document in general
this.usersDocument = document
}
);
The response part is worth discussing. I think in the RFC they won't return a DocumentModel
like I propose. Instead they return a JsonApiModel
that has an getter method document()
to access the top level attributes. Thus the programming API does not change. But this approach has a big disadvantage when adopting the RFC to this package. Because if you want to access the top level attributes of an empty collection this package will give you just an empty array as response. This is why I would propose to return a general DocumentModel
instead of JsonApiModel
or Array<JsonApiModel>
.
All other parts of the package should not change. This means if you do peek()
then you should get an JsonApiModel
on which you can call document()
to get the coresponding document including all the top level attributes like links()
and meta()
.
For testing this approach I did a very basic implementation in my jsonapi-document
branch and also adopted this changes into the client:
I'm going to further test this implementation next week but I just wanted to hook into the discussion about the roadmap with this proposal early so that you can consider this feature in further plans.
in the README it says that this library resolves infinite levels of relationships, but I think I it's just 2 levels, beacuase in JsonApiModel
syncRelationships()
is only called if the level is <= 1. Would there be any problem if this isn't limited?
Hi there,
I'm facing a new problem with the object that Datastore returns me after making a findRecord().
I just added a service in my application to store some shared states and variables between my components. This service is inspired by the Angular2-Webpack starter. As you can see, it contains getter and setter definitions to make sure you never set directly a property and you always get a clone of the state object.
get state() {
return this._state = this._clone(this._state);
}
set state(value) {
throw new Error('You should not mutate the `.state` directly. Use set(prop, value) instead');
}
get(prop?: any) {
const state = this.state;
return state.hasOwnProperty(prop) ? state[prop] : state;
}
set(prop: string, value: any) {
debugger
// Mutate our state internally
return this._state[prop] = value;
}
private _clone(object: InternalStateType) {
return JSON.parse(JSON.stringify( object ));
}
Here's for example one usecase in a component :
constructor(private route: ActivatedRoute,
public appState: AppState,
private datastore: Datastore){ }
ngOnInit(){
// Save current folder ID to the AppState service
let folderId = this.route.snapshot.params['id'];
this.appState.set('folderId', folderId);
console.log(this.appState.get('folderId')); // Works fine.
// Get current folder if needed
if (!this.folder && !this.appState.get('folder')){
this.datastore.findRecord(Folder, folderId)
.subscribe(
(folder: Folder) => {
this.appState.set('folder', folder);
console.log(this.appState.get('folder')) // Breaks here...
}
)
}
}
I have this output :
Uncaught TypeError: Converting circular structure to JSON(โฆ)
anywhere I'll call this.appState.get('folder')
I guess it's because all the properties added to my folder object, like _datastore node or in the constructor, the object can't be passed into the return JSON.parse(JSON.stringify( object ));
function.
What worry me is as for now I only use this basic state manager, but I'd like to implement something more substancial like ng2-redux, and I will likely encounter the same problem...
Any solution or workaround ?
Thx for your help :)
protected handleError(error: any): ErrorObservable;
Should be changed to
protected handleError(error: any): ErrorObservable<ErrorResponse>;
Hi there ,
I used JsonApi with RC2 and it worked fine . I hace upgraded my project to RC5 and after that I have a problem with using JsonApiDatastoreConfig objects.
I have a class like this:
@Injectable()
@JsonApiDatastoreConfig({
baseUrl: 'http://localhost:9010/datasets/',
models: {
dataset: MarketTradeDataset,
datasetSpecifications: DatasetSpecification,
marketTradeDatasetItems: MarketTradeDatasetItem,
markets: Market
}
})
export class DataSetDatastore extends JsonApiDatastore {
}
when I want to inject this class to one my services I have the below error:
main.ts:78 TypeError: Cannot read property 'type' of null
at eval (http://localhost:3000/node_modules/@angular/compiler/bundles/compiler.umd.js:13673:45)
at Array.forEach (native)
at getTransitiveModules (http://localhost:3000/node_modules/@angular/compiler/bundles/compiler.umd.js:13672:17)
at CompileMetadataResolver._getTransitiveNgModuleMetadata (http://localhost:3000/node_modules/@angular/compiler/bundles/compiler.umd.js:13387:37)
at CompileMetadataResolver.getNgModuleMetadata (http://localhost:3000/node_modules/@angular/compiler/bundles/compiler.umd.js:13259:47)
at eval (http://localhost:3000/node_modules/@angular/compiler/bundles/compiler.umd.js:13228:58)
at Array.forEach (native)
at CompileMetadataResolver.getNgModuleMetadata (http://localhost:3000/node_modules/@angular/compiler/bundles/compiler.umd.js:13215:48)
at eval (http://localhost:3000/node_modules/@angular/compiler/bundles/compiler.umd.js:13228:58)
at Array.forEach (native)
I tried to add JsonApiDatastore, JsonApiDatastoreConfig to my module.ts but I still have the same error.
Is anyone use this library with RC5?
Is there anyway to query nested resources like authors/1/books/2/reviews/3
?
I am using this angular2-jsonapi in the context of an Nativescript application. We use Nativescript-angular's NS_HTTP_PROVIDERS instead of HTTP_PROVIDERS. They basically extend the Http from Angular.
My issue is that the JsonApiDatastore completly ignores the provided Http from NS because it always creates an injector from the HTTP_PROVIDERS so none of my calls to our json-api work.
I think that, ideally, the http service should be injected directly in the JsonApiDatastore because it is the reponsiability of the consumer of this library to provide it.
Hi
I use findRecord method with include a relationship and sparse fieldsets:
return this.datastore.findRecord(Task, id, {
include: 'taskType',
fields: {
taskType: 'name',
}
});
Only "name" will selected on "taskType"
Now the second call of the method (and all others methods like query etc.)
return this.datastore.findRecord(Task, id, {
include: 'taskType',
fields: {
taskType: 'name,desciption,foo,far',
}
});
This will not update the fields "desciption,foo,far" in the model "taskType"
I can also see any functions to handle it. For example "clearStore", or removeFromStore
What can i do?
So, I fetching list of posts as described in example:
this.datastore.query(Post, {
page: { size: 10, number: 1}
}).subscribe(
(posts: Post[]) => console.log(posts)
);
But there is no information in response about pagination links if server returns it.
See
I want to start a discussion about supporting creation of embedded relationships. Currently the JSON API specification doesn't allow to create more than one entity in one request, but there are multiple issues to support it (json-api/json-api#1089, json-api/json-api#795).
I already implemented it, but don't know if I should create a pull-request, because it's not in the official spec yet: https://github.com/HennerM/angular2-jsonapi/blob/compound-resource-creation/src/services/json-api-datastore.service.ts#L107
What are your opinions on this topic?
Even if there is a PR for the delete record feature (#20), actually, I would prefer having the deleteRecord
on the model and not on the Datastore. Moreover, I would like to soft delete the record and then destroy it only when saving. Something like this:
this.datastore.findRecord(Post, '1').subscribe(
(post: Post) => {
post.deleteRecord();
post.isDeleted; // true
post.save(); // => DELETE /posts/1
}
);
While for immediately deleting the method, I would like to use:
this.datastore.findRecord(Post, '2').subscribe(
(post: Post) => {
post.destroyRecord(); // => DELETE /posts/2
}
);
The only tricky thing is handling the rollbackAttributes()
method on a deleted record, before saving it.
Like the rest of the interface, this is inspired by EmberData.
Do you like this approach or do you prefer having the deleteRecord
on the Datastore?
I am calling a JsonApi service that requires OAuth2 authentication. It would be cool, if we could set custom HTTP headers somehow...
Btw.. nicely done!
Hi guys, can you help me please ? I not sure if it issue or it problem of JSON API
Example of JSON API response
{
"success": true,
"response": {
"data": [
{
"type": "products",
"id": "7",
"attributes": {
"id": "7",
"urlCode": "regular-e-8713568281133",
"title": "Sparta regular e e-bike"
},
"links": [],
"relationships": []
}
]
},
"error": "",
"ver": 1
}
As you can see, field data not in the root of response, and i have this error https://www.screencast.com/t/HFRquYLD.
I see that in private method JsonApiDatastore::extractQueryData you trying to get it from root.
Are there any options to provide correct work with custom response?
Hi guys,
Currently, code that parse responses and generate payloads for requests spread out between two components JsonApiDatastore
and JsonApiModel
. This cause unnecessary complexity of each component and high coupling between them. Code is a bit messy and it hard to test it. Also it's not flexible because end user couldn't change any parts of data handling process.
I think that we should refactor this code to series of separate components - serializers. We should have three types of serializers:
ResponseSerializer
- it should be able to convert response data to DocumentModel
(see #26). Under hood it should use models serializers (see below) to convert separate resources.RequestSerializer
- it should be able to convert specified JsonApiModel
to request payload. Again, under hood it should use models serializers to convert separate resource.ModelSerializer
- it should support two things: unserialize part of response data to JsonApiModel
instance and serialize JsonApiModel
instance into part of request payload.All serializers should be configurable. I.e. we need to support following scenarios:
JsonApiModel
Please let me know what you think about it.
Hi,
do you plan to add a "patch" or a generic "save" method to the jsonapi-data-store.service?
Best whishes
Hey.
The answer comes back clean model without headers. whether they can somehow get it?
I have my parse server running in app-engine.
after initializing parse i could't fetch the objects, no idea how to move further.
Is their any alternative jsonapi to sync parse sdk classes?
Thanks in advance
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.