From 2b1a9ae30f5005016722403efa6703188fb7d261 Mon Sep 17 00:00:00 2001 From: larkin Date: Wed, 22 Jul 2020 16:50:52 +0300 Subject: [PATCH 1/2] feat(JsonApiDatastore): Remove BelongsTo relationship Ability to remove BelongsTo relationship by setting data to null --- .../services/json-api-datastore.service.ts | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/projects/angular2-jsonapi/src/services/json-api-datastore.service.ts b/projects/angular2-jsonapi/src/services/json-api-datastore.service.ts index 34ffe0b4..7ed8bcfd 100644 --- a/projects/angular2-jsonapi/src/services/json-api-datastore.service.ts +++ b/projects/angular2-jsonapi/src/services/json-api-datastore.service.ts @@ -1,16 +1,18 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpErrorResponse, HttpHeaders, HttpResponse } from '@angular/common/http'; -import find from 'lodash-es/find'; -import { catchError, map } from 'rxjs/operators'; import { Observable, of, throwError } from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; + +import find from 'lodash-es/find'; +import * as qs from 'qs'; +import 'reflect-metadata'; + import { JsonApiModel } from '../models/json-api.model'; import { ErrorResponse } from '../models/error-response.model'; import { JsonApiQueryData } from '../models/json-api-query-data'; -import * as qs from 'qs'; import { DatastoreConfig } from '../interfaces/datastore-config.interface'; import { ModelConfig } from '../interfaces/model-config.interface'; import { AttributeMetadata } from '../constants/symbols'; -import 'reflect-metadata'; export type ModelType = new(datastore: JsonApiDatastore, data: any) => T; @@ -287,6 +289,14 @@ export class JsonApiDatastore { data: relationshipData }; } + } else if (data[key] === null) { + const entity = belongsToMetadata.find((it: any) => it.propertyName === key); + if (entity) { + const relationshipKey = entity.relationship; + relationships[relationshipKey] = { + data: null + }; + } } } } @@ -461,6 +471,10 @@ export class JsonApiDatastore { for (const relationship in relationships) { if (relationships.hasOwnProperty(relationship) && model.hasOwnProperty(relationship)) { const relationshipModel: JsonApiModel = model[relationship]; + if (relationshipModel === null) { + continue; + } + const hasMany: any[] = Reflect.getMetadata('HasMany', relationshipModel); const propertyHasMany: any = find(hasMany, (property) => { return modelsTypes[property.relationship] === model.constructor; From 676976b744b53fc228c30ab9f96bba162892757b Mon Sep 17 00:00:00 2001 From: larkin Date: Wed, 22 Jul 2020 17:55:27 +0300 Subject: [PATCH 2/2] feat(JsonApiDatastore): Remove BelongsTo relationship Ability to remove BelongsTo relationship by setting data to null --- .../json-api-datastore.service.spec.ts | 29 ++++++++++++++++++- .../services/json-api-datastore.service.ts | 1 + 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/projects/angular2-jsonapi/src/services/json-api-datastore.service.spec.ts b/projects/angular2-jsonapi/src/services/json-api-datastore.service.spec.ts index eb896011..d2bca622 100644 --- a/projects/angular2-jsonapi/src/services/json-api-datastore.service.spec.ts +++ b/projects/angular2-jsonapi/src/services/json-api-datastore.service.spec.ts @@ -3,7 +3,7 @@ import { parseISO } from 'date-fns'; import { Author } from '../../test/models/author.model'; import { Chapter } from '../../test/models/chapter.model'; import { AUTHOR_API_VERSION, AUTHOR_MODEL_ENDPOINT_URL, CustomAuthor } from '../../test/models/custom-author.model'; -import { AUTHOR_BIRTH, AUTHOR_ID, AUTHOR_NAME, BOOK_TITLE, getAuthorData } from '../../test/fixtures/author.fixture'; +import { AUTHOR_BIRTH, AUTHOR_ID, AUTHOR_NAME, BOOK_TITLE, getAuthorData, getIncludedBooks } from '../../test/fixtures/author.fixture'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { API_VERSION, BASE_URL, Datastore } from '../../test/datastore.service'; import { ErrorResponse } from '../models/error-response.model'; @@ -695,5 +695,32 @@ describe('JsonApiDatastore', () => { saveRequest.flush({}); }); + + it('should remove empty BelongsTo-relationship', () => { + const BOOK_NUMBER = 2; + const DATA = getAuthorData('books', BOOK_NUMBER); + const author = new Author(datastore, DATA); + author.syncRelationships(DATA, getIncludedBooks(BOOK_NUMBER, 'books.category')); + + expect(author.books).toBeDefined(); + expect(author.books.length).toBe(BOOK_NUMBER); + + const firstBook = author.books[0]; + expect(firstBook.category).toBeDefined(); + expect(firstBook.category.name).toBeDefined(); + + const expectedUrl = `${BASE_URL}/${API_VERSION}/books/${firstBook.id}`; + + firstBook.category = null; + firstBook.save().subscribe(); + + const saveRequest = httpMock.expectOne({method: 'PATCH', url: expectedUrl}); + const obj = saveRequest.request.body.data; + expect(obj.relationships).toBeDefined(); + expect(obj.relationships.category).toBeDefined(); + expect(obj.relationships.category.data).toBeNull(); + + saveRequest.flush({}); + }); }); }); diff --git a/projects/angular2-jsonapi/src/services/json-api-datastore.service.ts b/projects/angular2-jsonapi/src/services/json-api-datastore.service.ts index 7ed8bcfd..8ff531bc 100644 --- a/projects/angular2-jsonapi/src/services/json-api-datastore.service.ts +++ b/projects/angular2-jsonapi/src/services/json-api-datastore.service.ts @@ -292,6 +292,7 @@ export class JsonApiDatastore { } else if (data[key] === null) { const entity = belongsToMetadata.find((it: any) => it.propertyName === key); if (entity) { + relationships = relationships || {}; const relationshipKey = entity.relationship; relationships[relationshipKey] = { data: null