14

on my server side I have a Java object that contains a HashMap. I want to serialize it to JSON, return it to my Angular2 client and use it as a Map/Dictionary there.

Here's the class:

public class FileUploadResult {
    String timestamp;
    String message;
    String status;
    HashMap<String, String> parameters;

    public FileUploadResult(String status, String message, String timestamp, HashMap parameters) {
        this.status = status;
        this.message = message;
        this.timestamp = timestamp;
        this.parameters = parameters;
    }

}

Here's the JSON that I receive on the client side:

{"timestamp":"","message":"Test","status":"1","parameters":{"myKey":"Value","mySecondKey":"Another Value"}}

Here's my receiving Angular2 http call:

this.http.post(this.uploadURL, formData).map((res:Response) => res.json() as FileUploadResult).catch(this.handleError); 

FileUploadResult on the client looks like this:

export class FileUploadResult {
    status: string;
    timestamp: string;
    message: string;
    parameters: Map<string, string>;

    constructor() {
        this.parameters = new Map<string, string>();
    }

    addParameter(key: string, value: string) {
        this.parameters.set(key, value);
    }

    getParameters() {
        return this.parameters;
    }
}

By using the "as FileUploadResult" in the http.map call, I expected to get an object on where I can call result.getParameters().get("myKey"). But that's not happening. I get an unspecified object where the only call that works is result.parameters.myKey. Is there a way to achieve what I want and to cast the JSON object to the FileUploadResult including the Angular2 map?

Androidicus
  • 1,688
  • 4
  • 24
  • 36

2 Answers2

18

The result of calling res.json() is a javascript object which can be accessed like so:

let json = res.json();
console.log(json["timestamp"]);
console.log(json.message);

The way to describe such an object in typescript is using an interface (or type alias):

interface JsonResponse {
    timestamp: string;
    message: string;
    status: string;
    parameters: { [name: string]: string };
}

If you want to transform this object into your class you'll need to do something like:

class FileUploadResult {
    status: string;
    timestamp: string;
    message: string;
    parameters: Map<string, string>;

    constructor(json: JsonResponse) {
        this.status = json.status;
        this.timestamp = json.timestamp;
        this.message = json.message;

        this.parameters = new Map<string, string>();
        Object.keys(json.parameters).forEach(key => {
            this.addParameter(key, json.parameters[key]);
        });
    }

    addParameter(key: string, value: string) {
        this.parameters.set(key, value);
    }

    getParameters() {
        return this.parameters;
    }
}

(code in playground)

Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299
1
 class FileUploadResult {
    parameters: Record<string, string> = {};

    addParameter(key: string, value: string) {
       this.parameters[key] = value;
    }
}

You can use it this way

const abc = new FileUploadResult();
abc.addParameter('hi', 'hello');
console.log(abc.parameters);   // will log {hi: "hello"}

https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt

aWebDeveloper
  • 36,687
  • 39
  • 170
  • 242