0

I have a very simple Angular2 app running locally. I'm using a service to send an instance of an object to a webservice API. The API validates JSON against a schema, and ID's must be numbers (i.e. NOT quoted in the JSON).

My problem is that when I try to send the object to the webservice, my ID field has quotes around it, even though it's typed to be a number in Typescript.

The behaviour is only observed when the nameproperty of the object contains "special characters".

I've tested and found that it doesn't seem to be the JSON.stringify I use — please see code below.

The app is written in Typescript.

Unit class:

export class Unit {
    id: number;   // This is the problem child
    name: string; // This is the string that can contain special characters
    short: string;
    triggers_plural: number;
    is_headline: boolean;
}

Method to save:
My code for saving an instance of Unit to the webservice:

updateUnit(unit: Unit): Promise<Unit>
{
    var objSend = {unit_data: [unit]};          // Webservice expects an array of units

    console.log(objSend.unit_data[0].id === 2); // Yields false when ID is 2
    console.log(objToReturn);                   // Logs ID to verify it is 2 when testing

    // Code for actual request
    return this.http.put(`${this.unitUrl}/${unit.id}`, JSON.stringify(objSend),{headers:this.headers})
    .toPromise()
    .then(()=> unit)
    .catch(this.handleError);
}

When running the code and calling the method, the console will log that the ID is NOT equal when the Unit object's name property contains special characters.

Example without special characters (no problem, id is a number):

Example WITH special characters (eek! Id is a string!):

The updateUnit method is called from my unit-detail component where you can edit a unit:

export class UnitDetailComponent implements OnInit {
    unit: Unit; // this.unit later on

    constructor(
        private unitService: UnitService,
        private route: ActivatedRoute
    ){}

    ngOnInit(): void
    {
        this.route.params.forEach((params: Params) => {
            let id = +params['id']; // The routing will give id to look for
            this.unitService.getUnit(id)
            .then(unit => this.unit = unit); // Here the unit is instanciated in the first place
        });
    }

    save(): void
    {
        this.unitService.updateUnit(this.unit).then(this.goBack); // Here is the call to updateUnit method
    }
}

It's bound to an input in the template:

<div *ngIf="unit">
    <div>
        <label>Edit unit</label>
        <div>
          <input type="text" [(ngModel)]="unit.name" />
        </div>
    </div>
    <button class="btn btn-default" type="button" (click)="save()">Save</button>
</div>

Maybe the problem arises already when the two-way data binding is filling in the name property when you write something in the <input> but I don't understand how the type of the id can change?

Link to github repos of the whole project: https://github.com/djoike/ng2-cookbook/tree/master-so

12
  • Interesting Bug, where does unit_data come from? Is it already a string when updateUnit is called? Commented Sep 18, 2016 at 20:51
  • On the line you mention, I'm simply creating an object (objSend) with a property "unit_data", and so It's not existing anywhere before on that line. Commented Sep 18, 2016 at 20:55
  • but unit (the argument) comes from somewhere right? ... Commented Sep 18, 2016 at 20:56
  • Yes, it's passed into the function on the line above: updateUnit(unit: Unit) Commented Sep 18, 2016 at 20:57
  • 1
    Ok, but that means the error is where the unit object is originally actually created and not within the function you gave us so where is updateUnit called? Commented Sep 18, 2016 at 21:06

1 Answer 1

1

A small solution is to cast the field to any , and then convert it to a number using parseInt(), I faced a similar problem just today

for more info about casting, check the Type assertions section here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.