Angular 2 Typescript: Is it possible to pass an interface as a parameter to a function?


Ole Spaarmann

I have the following problem: I am pulling data from JSON API. Currently, I serve each data model (e.g. article, user, etc.) and provide a model class for each data model. But this is crazy and not really maintainable. So I want to refactor to have one interface and one model class for each data model and a unified model DataAPIService.

The problem is that DataAPIServicethe functions in that query API should not return JSON, but an object or collection of objects of the queried type. So I need a way to pass an interface or type into the query method of the service and then initialize a new object of this type.

is it possible? Do I make sense? Here 's some code to help you understand what I mean and show the current progress.

import { Injectable } from '@angular/core';

import { AuthHttp } from 'angular2-jwt';
import 'rxjs/add/operator/map';

import { Config } from '../config/env.config';

@Injectable()
export class DataAPIService {

  constructor(
    private authHttp: AuthHttp
  ) {}

  // This function will be called to retrieve data (for example from a Component). 
  // I want to pass in the object type or interface so that I only have one 
  // getIndex() function and not one for every data type.

  getIndex(page:number = 1, object_name:string, object_type) {
    return this.authHttp.get(Config.API_ENDPOINT + '/' + object_name + '?page=' + page)
      .map(res => res.json())
      .map(res => {
        return this.fromJson(res.data, object_type);
      });
  }

  // This function just checks which attributes are present in the object type 
  // and fills a new object of this type with the values from JSON.  
  // This is partly pseudo-code since I don't know how to solve this.

  fromJson(input_json: any, object_type) {
    // The next line is obviously not working. This is what I'm trying to figure out
    var object:object_type = new object_type();
    var json_attributes = input_json.attributes;
    for (var key in json_attributes) {
      if (object.hasOwnProperty(key)) {
        object[key] = json_attributes[key];
      }
    }
    object.id = input_json.id;
    return object;
  }

}
Ole Spaarmann

This is how I solved the whole problem. What's important to me is that the resulting object is not a generic object, but an object of type Post. I also want to use interfaces and I want the initialization of the objects to be easy.

First, I have a base class that inherits all data models.

Basic model. Model

import * as _ from 'lodash';

export class BaseModel {

  public id: string;
  [key: string]: any;

  constructor(private data?: any) {
    // This basically does the initialization from a variable json object. 
    // I later on just pass the json data into the constructor.
    if (data) {
      this.id = data.id;
      _.extend(this, data.attributes);
    }
  }
}

Now, the actual model inherited from the base model:

member.model.ts

// The actual model. It has an interface and extends the base class 
// (so that the main logic is just in one place - DRY)

import { BaseModel } from './base-model.model';

interface MemberInterface {
  email:string;
  name:string;
}

export class Member extends BaseModel implements MemberInterface {

  email:string;
  name:string;

  constructor(data?: any) {
    super(data);
  }

}

Let's use it. Via a service that can pull data from an API

import { Injectable } from '@angular/core';
import { AuthHttp } from 'angular2-jwt';
import 'rxjs/add/operator/map';
import { Config } from '../config/env.config';

@Injectable()
export class MemberService {

  constructor(public authHttp: AuthHttp) {}

  // Calls the API and returns the result.
  // authHttp works very similar to http. Just with added JWT protection
  // check it out on GitHub: angular2-jwt
  getIndex(page:number = 1):any {
    let url = [Config.API_ENDPOINT, 'members', '?page='].join('/');
    return this.authHttp.get(url + page)
      .map(res => res.json())
      .map(res => {
        return res;
      });
  }

  // Simpler example when just getting one entry
  getOne(id: string):any {
    let url = [Config.API_ENDPOINT, 'members', id].join('/');
    return this.authHttp.get(url)
      .map(res => res.json())
      .map(res => {
        return res;
      });
  }


}

Finally, let's use the Model class and Service together

import { Component, OnInit } from '@angular/core';

import { MemberService } from '../shared/index';
import { Member } from '../shared/models/member.model';

@Component({
  moduleId: module.id,
  selector: 'app-member-list',
  templateUrl: 'member-list.component.html',
  styleUrls: ['member-list.component.css']
})
export class MemberListComponent implements OnInit {

  private members: Array<Member>;
  private member: Member;

  constructor(private memberService: MemberService) {
    this.members = [];
    this.member = new Member();
  }

  ngOnInit():any {
    // Pull the list on initialization
    this.getIndex(1);
  }

  // For the index
  getIndex(page:number = 1):Array<Member> {
    this.memberService.getIndex(page).subscribe(
      res => {
        this.members = [];
        for(let i = 0; i < res.data.length; i++) {
          let member = new Member(res.data[i]);
          this.members.push(member);
        }
      },
      err => console.log(err)
    );
  }

  // Simpler version with just one entry 
  getOne():any {
    this.memberService.getIndex(page).subscribe(
      res => {
        this.member = new Member(res.data.attributes);
      },
      err => console.log(err)
    );
  }

}

Related


Typescript - pass interface literal to function parameter

Paul Redmond I want to use an interface to set data types and then call them in a function while setting default values without passing the data . I am getting the after canvas error ',' expected.in the function . Can't I call it that? // Options interface opt

Typescript - pass interface literal to function parameter

Paul Redmond I want to use an interface to set data types and then call them in a function while setting default values without passing the data . I am getting the after canvas error ',' expected.in the function . Can't I call it that? // Options interface opt

Typescript - pass interface literal to function parameter

Paul Redmond I want to use an interface to set data types and then call them in a function while setting default values without passing the data . I am getting the after canvas error ',' expected.in the function . Can't I call it that? // Options interface opt

Typescript - pass interface literal to function parameter

Paul Redmond I want to use an interface to set data types and then call them in a function while setting default values without passing the data . I am getting the after canvas error ',' expected.in the function . Can't I call it that? // Options interface opt

Typescript - pass interface literal to function parameter

Paul Redmond I want to use an interface to set data types and then call them in a function while setting default values without passing the data . I am getting the after canvas error ',' expected.in the function . Can't I call it that? // Options interface opt

Typescript pass function as parameter

Joachim connectWebSocket() { const socket = new SockJS('http://localhost:8080/websocket'); this.stompClient = Stomp.over(socket); const _this = this; this.stompClient.connect({ "Authorization" : "Bearer "+localStorage.getItem("Authorization"

Angular 2 pass parameter to validator function

Ohm 27 I have an array in my formcomponent class and would like to be able to pass that array to the validator function. I am using the Validators.compose function when adding multiple validators to the form. However, this only accepts the name of the validato

Angular 2 pass parameter to validator function

Ohm 27 I have an array in my formcomponent class and would like to be able to pass that array to the validator function. I am using the Validators.compose function when adding multiple validators to the form. However, this only accepts the name of the validato

Angular 2 pass parameter to validator function

Ohm 27 I have an array in my formcomponent class and would like to be able to pass that array to the validator function. I am using the Validators.compose function when adding multiple validators to the form. However, this only accepts the name of the validato

Pass function as JSON data in angular 2 typescript

and all this I'm using angular 2.0.0 with Typescript and trying to build a dynamic menu system based on a JSON array received by a component. var menu = [ {id:"menu1", title: " Menu 1", action: "addUser()"}, {id:"menu2", title: " Menu 2", action: "addPhoto()"}

Pass function as JSON data in angular 2 typescript

and all this I'm using angular 2.0.0 with Typescript and trying to build a dynamic menu system based on a JSON array received by a component. var menu = [ {id:"menu1", title: " Menu 1", action: "addUser()"}, {id:"menu2", title: " Menu 2", action: "addPhoto()"}

Pass function as JSON data in angular 2 typescript

and all this I'm using angular 2.0.0 with Typescript and trying to build a dynamic menu system based on a JSON array received by a component. var menu = [ {id:"menu1", title: " Menu 1", action: "addUser()"}, {id:"menu2", title: " Menu 2", action: "addPhoto()"}

Pass function as JSON data in angular 2 typescript

and all this I'm using angular 2.0.0 with Typescript and trying to build a dynamic menu system based on a JSON array received by a component. var menu = [ {id:"menu1", title: " Menu 1", action: "addUser()"}, {id:"menu2", title: " Menu 2", action: "addPhoto()"}

Pass function as JSON data in angular 2 typescript

and all this I'm using angular 2.0.0 with Typescript and trying to build a dynamic menu system based on a JSON array received by a component. var menu = [ {id:"menu1", title: " Menu 1", action: "addUser()"}, {id:"menu2", title: " Menu 2", action: "addPhoto()"}

Pass an interface as a function parameter (PHP)?

username I'm watching one of Jeffs Laracast's tutorials on coding rules. function signUp($subscription) { if ($subscription == 'monthly') { $this->createMonthlySubscription(); } elseif ($subscription == 'forever') { $this->

Pass an interface as a function parameter (PHP)?

username I'm watching one of Jeffs Laracast's tutorials on coding rules. function signUp($subscription) { if ($subscription == 'monthly') { $this->createMonthlySubscription(); } elseif ($subscription == 'forever') { $this->

Pass an interface as a function parameter (PHP)?

username I'm watching one of Jeffs Laracast's tutorials on coding rules. function signUp($subscription) { if ($subscription == 'monthly') { $this->createMonthlySubscription(); } elseif ($subscription == 'forever') { $this->

Pass an interface as a function parameter (PHP)?

username I'm watching one of Jeffs Laracast's tutorials on coding rules. function signUp($subscription) { if ($subscription == 'monthly') { $this->createMonthlySubscription(); } elseif ($subscription == 'forever') { $this->

Pass an interface as a function parameter (PHP)?

username I'm watching one of Jeffs Laracast's tutorials on coding rules. function signUp($subscription) { if ($subscription == 'monthly') { $this->createMonthlySubscription(); } elseif ($subscription == 'forever') { $this->

Convert interface to Function parameter in Typescript

Aylton Almeida What I want to know is if it is possible to use an interface to describe the parameters that need to be passed to a function. An example is as follows: interface Person { name: string; age: number; } function createPerson(n

Convert interface to Function parameter in Typescript

Aylton Almeida What I want to know is if it is possible to use an interface to describe the parameters that need to be passed to a function. An example is as follows: interface Person { name: string; age: number; } function createPerson(n

Convert interface to Function parameter in Typescript

Aylton Almeida What I want to know is if it is possible to use an interface to describe the parameters that need to be passed to a function. An example is as follows: interface Person { name: string; age: number; } function createPerson(n

Convert interface to Function parameter in Typescript

Aylton Almeida What I want to know is if it is possible to use an interface to describe the parameters that need to be passed to a function. An example is as follows: interface Person { name: string; age: number; } function createPerson(n

Typescript: Pass function as type in interface

Samuel Hudec I'm trying to figure out how to get a type from an existing Typescript function and use it to define an interface. I'm working on a React project and I want to pass ( action creatorfunctionality) into Propsan interface and then as a pass into a Re