Skip to content

Conversation

@HennerM
Copy link
Collaborator

@HennerM HennerM commented Aug 25, 2017

Feature to explicitly override attribute names used for serialization.
Can be used to solve use cases like #86 .

@mernen I would appreciate if you also can take a look please.

@HennerM HennerM requested a review from ghidoz August 25, 2017 12:59
@coveralls
Copy link

Coverage Status

Coverage increased (+0.9%) to 84.043% when pulling 4970a1f on optional-parameter-names into 84f7e85 on master.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage increased (+0.9%) to 84.043% when pulling 4970a1f on optional-parameter-names into 84f7e85 on master.

Copy link
Contributor

@mernen mernen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, and my comments are about fairly minor things.

But there are two things that caught my attention:

  1. Mutating the input object in transformSerializedNamesToPropertyNames makes me a bit uneasy, and can lead to data loss as I described in the comment.
  2. If I understood it correctly, getAttributePropertyNames will be called for every object being deserialized, which will then loop through all properties to rebuild that name/property map. Feels a bit wasteful.

Thinking about it, maybe the deserialization/renaming logic could be moved to JsonApiModel's constructor, replacing its Object.assign() with a loop through the declared attributes. I believe this could provide a number of benefits:

  1. The data parameter to JsonApiModel's constructor could be defined as being the raw object received from the server. Nothing more, nothing less. (i.e. attributes names and values are in their raw form)
  2. No intermediary objects or loops would be needed.
  3. No risk of data loss during mutation, even if the attribute names and serialized names form some kind of tangle.

Sorry if this explanation is not clear, I could make a simple commit on top of this one to demonstrate.

import find from 'lodash-es/find';
import { Observable } from 'rxjs/Observable';
import { JsonApiDatastore, ModelType } from '../services/json-api-datastore.service';
import {isPropertyAssignment} from 'codelyzer/util/astQuery';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m guessing this was an accidental import?

if (data) {
this.id = data.id;
Object.assign(this, data.attributes);
if (data.attributes) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason for this test? I just checked the spec, and it says it’s safe to pass null or undefined.

import * as dateParse from 'date-fns/parse';

export function Attribute(config: any = {}) {
export function Attribute(serializedName: string = null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would fail under strictNullChecks. Could it instead be an optional?

export function Attribute(serializedName?: string) {

for (let propertyName in attributesMetadata) {
if (attributesMetadata.hasOwnProperty(propertyName)) {
let metadata: any = attributesMetadata[propertyName];
console.log(metadata);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgotten debug? :)

Object.keys(serializedNameToPropertyName).forEach(serializedName => {
if (attributes[serializedName]) {
attributes[serializedNameToPropertyName[serializedName]] = attributes[serializedName];
delete attributes[serializedName];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this would completely erase the value if the library user passes the same serialized name as the property name, e.g.:

@Attribute("name") name: string;

This could be guarded by either @Attribute or getAttributePropertyNames, but it gets trickier if for whatever reason the developer wants to flip fields around, e.g.:

@Attribute("first-name") name: string;
@Attribute("last-name") surname: string;
@Attribute("name") fullName: string;

In this case, by the time the deserializer got to fullName, it would delete the name that was assigned before.

name: string;

@Attribute()
@Attribute("dob")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use single quotes, per tslint. (For some reason, though, the lint script is not warning about this)

@HennerM HennerM added this to the v4.0.0 milestone Sep 24, 2017
@HennerM HennerM force-pushed the optional-parameter-names branch from 4970a1f to 7e43266 Compare September 24, 2017 17:24
@coveralls
Copy link

coveralls commented Sep 24, 2017

Coverage Status

Coverage increased (+0.6%) to 87.468% when pulling 7e43266 on optional-parameter-names into 316e320 on master.

@coveralls
Copy link

coveralls commented Sep 24, 2017

Coverage Status

Coverage increased (+0.6%) to 87.468% when pulling 22cf1a9 on optional-parameter-names into 316e320 on master.

@HennerM HennerM merged commit ed59e60 into master Sep 24, 2017
@safo6m safo6m deleted the optional-parameter-names branch September 17, 2018 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants