11

I have a typescript class as below:

export class ImageItem{
    constructor(public Id: number, public ImageUrl: string, public Caption: string, public Description: string, private _sanitizer: DomSanitizer)
    {
    }
}

all the constructor's parameters are properties that are related to that class but the last item is a class which is injected into my class. My problem is if I want to create an object of this class I want to do something as below:

var a=new ImageItem(1, 'image1', 'http://aaa.com/aa.jpg', '')

But it gives me an error because of the injected item. I was wondering how I should solve this issue.

4
  • 1
    If the class needs a DomSanitizer to work correctly, why aren't you passing one? And if it doesn't need a DomSanitizer, why does the constructor expect one? That's what you should wonder. Commented Aug 19, 2017 at 11:55
  • Because It is an injected object. I don't want somebody who using ImageItem to consider it. Commented Aug 19, 2017 at 11:59
  • No. Angular injects services, but not data like description or caption. And that doesn't change anything to my question. If you don't pass it when creating the object, and it needs it to work, all you'll have is an object that will not behave as it should. Commented Aug 19, 2017 at 12:15
  • And if this object is supposed to be created and injected by Angular, then you shouldn't create it youself. Commented Aug 19, 2017 at 12:19

1 Answer 1

15

What you need is a factory service that is able to create instances of this kind of class and at the same time injects the properties you would like to have injected.

It would look something like this.

The image-item.ts defines a simple class:

import { DomSanitizer } from '@angular/platform-browser';

export class ImageItem {
    constructor(public Id: number, public ImageUrl: string, public Caption: string, 
                  public Description: string, private _sanitizer: DomSanitizer) {
    }
}

The factory is an injectable service that injects the DomSanitizer and has a method able to create instances of ImageItem.

import { Injectable } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { ImageItem } from './image-item';

@Injectable()
export class ImageItemFactoryService {

  constructor(private domSanitizer: DomSanitizer) { }

  public createImageItem(id: number, description: string) {
    return new ImageItem(id, '', '', description, this.domSanitizer);
  }
}

The app.component.ts imports the factory as a provider and uses it to create instances of ImageItem.

import { Component } from '@angular/core';
import { ImageItem } from './image-item';
import { ImageItemFactoryService } from './image-item-factory.service';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [ImageItemFactoryService]
})
export class AppComponent {
  private item: ImageItem = null;
  constructor(public imageItemFactory: ImageItemFactoryService) {
    this.item = imageItemFactory.createImageItem(1, 'something');
  }
}

In angularjs(1) it was possible to use the injector in order to create an instance and it was possible at the same time to give some local values to be used during injection.

In angular (2) however the Injector service no longer provides that functionality.

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

4 Comments

is there any better solution nowadays?
@Fraga nope. This is prettty much the standard way of doing it in any OOP language, I dont think you'll find a better way.
So, I'm undestanding then, that is not a best practices to put logic in models. In that case is preferable to place all the logic in a services and inside that service call all the services you need and fill the model rigth?
Yes. Models should hold state. You can have a look at Redux(ngrx-store) for an example of this.

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.