4

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?

2
  • Do you mean, you want retrieve 'modelObject.detail.name'? You want to know the name of the value being passed in, not the actual value? Commented Jan 27, 2017 at 19:10
  • Yep that's exactly what i need Commented Jan 27, 2017 at 19:15

4 Answers 4

3

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!

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

Comments

0

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.

5 Comments

This unfortunately would not work, as the rendering converts the object into [object Object]
Did you try it?
yes. heres a plunker: plnkr.co/edit/uJH17jhWxeJlfMjxUPoj but this does not even keep the input property in the DOM. I've seen it rendered multiple times as [object Object] though
Angular strips away all of your bound properties during compile time. You wouldn't even see [object Object] if you ran it in production mode.
Neh you're right. The original nodes from the template will only be added after compilation, than the original attribute is gone... Too bad.. Let's think some more :-)
0

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];
    ) }    
}

Comments

-1

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

6 Comments

It's not interpolation I'm looking for. I'm trying to access the string value passed to the input attribute from my controller for use with one of my services.
you've already done that haven't you using "this.DataProperty" in your child component. If you console log "this.DataProperty", it would print the value
I don't want the value since I already have it. I want the string literal i.e. "modelObject.detail.name". Also, interpolation isn't necessary because the ngModel directive already binds the model value to the text in the input
Not sure this is what John is asking for. He's asking how to get the name of the value being passed in, not the value.
You can't make the child component literary print "modelObject.detail.name", what good would that do
|

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.