john_mc
john_mc

Reputation: 1376

How to read the string value of a component's input attribute binding in Angular 2?

I have a simple form input component in my angular2 app which contains an @Input binding to the attribute [dataProperty]. As you may have guessed, the [dataProperty] attribute is a string value of the format: [dataProperty]="modelObject.childObj.prop", where the modelObject is the model shared throughout my application. Basically, I'm using this @Input attribute to pass the model from a parent component to my <custom-text-input> component, where it is then bound by [ngModel] to the nested component's input.

Everything works as intended and in my controller; i.e. when I access this.dataProperty the value on the model to which the input binds is returned. What I can't seem to find out, however, is how to access the string literal passed to [dataProperty] from the template in the first place.

Component:

@Component{
    selector: "custom-text-input",
    template: "<input type="text" [ngModel]="dataProperty"></input>
}

export Class customInputComponent implements OnInit {
    @Input() dataProperty: string;

    /**
       ex of modelObject: { detail: { name: "Cornelius" } }
       (^^^ would originate in parent component ^^^)
    */

    constructor() {}

}

Use Case:

<div class=wrapper>
    <custom-text-input [dataProperty]="modelObject.detail.name">
    </custom-text-input>
</div>

Basically, when I go to access this.DataProperty from the component controller it returns "Cornelius". Is it possible to access the string literal so that I can capture the "modelObject.detail.name" string from my controller as well?

Upvotes: 4

Views: 7907

Answers (4)

Mezo Istvan
Mezo Istvan

Reputation: 2772

Unfortunately, angular 2 uses the default conversion from Object to string, in this case, and will only display the familiar [object Object] in the DOM. You cannot get more information out of that.

Also, the object does not know anything about its parent object. See: Access parent's parent from javascript object

You could use something like Somo's answer: provide the value as a property of an object. The name of the property should be the string literal, the value of the property should be the actual value.

Use Case:

<div class="wrapper">
    <custom-text-input [dataProperty]="{'modelObject.detail.name': modelObject.detail.name}">
    </custom-text-input>
</div>

Component:

@Component{
    selector: "custom-text-input",
    template: "<input type="text" [ngModel]="actualValue"></input>
}

export Class customInputComponent implements OnInit {
    @Input() dataProperty: Object;
    actualValue: string;

    ngOnInit() { 
        console.log( Object.keys( dataProperty )[0] );
        console.log( Object.values( dataProperty )[0] );
        this.actualValue = Object.values( dataProperty )[0];
    ) }    
}

Upvotes: 0

Somo  S.
Somo S.

Reputation: 4185

I would create a key-value pair of the property and it's name and pass them in together like so:

<div class="wrapper">
    <custom-text-input [dataProperty]="{modelObject.detail.name}">
    </custom-text-input>
</div>

Then I would gain access to the property name by doing something like this:

@Component{
    selector: "custom-text-input",
    template: "<input type="text" [ngModel]="dataProperty"></input>
}
export Class customInputComponent {

    dataPropertyName;

    private _dataProperty;    
    @Input() 
    set dataProperty( keyValuePair ){
      this._dataProperty = Object.values(keyValuePair)[0]
      this.dataPropertyName = Object.keys(keyValuePair)[0]
    }
    get dataProperty( ){
      console.log( "I have the property name here:" + this.dataPropertyName )
      return this._dataProperty
    }

}

Hope this helps!

Upvotes: 3

MikeOne
MikeOne

Reputation: 4912

Technically, this should be possible. But you have to think somewhat out of the box. The element with the dataProperty is, in the end, just a HTML node.

<custom-text-input [dataProperty]="modelObject.detail.name">

I'm not in a position at the moment to create an example for you, but you could simple get a reference to the components HTML (using Angular viewReference in your component) and simply query the attribute on it. Pseudo code would something like

 let myString = viewref.nativeElement.getAttribute('[dataProperty]')

Again, I haven't tested it, but I see no reason why this wouldn't work.

Upvotes: 0

Sumama Waheed
Sumama Waheed

Reputation: 3609

Edit

So it looks like the question is about printing the name of the variable instead of the value. That's not possible.

You can access the value from the controller:

export Class customInputComponent implements OnInit {
    @Input() dataProperty: string; 

    constructor() {
       console.log(this.dataProperty) // would print modelObject.childObj.prop
    }

}

If your asking about Interpolation, you do this:

{{dataProperty}} <input type="text" [ngModel]="dataProperty"></input>

More info:

https://angular.io/docs/ts/latest/guide/template-syntax.html

Upvotes: -1

Related Questions