I am using ngx-popover, when try to open it from another component it was showing the following error
Cannot read property 'show' of undefined
below is the following code. home.html is the parent component
In
home.html
<button (click)="onShowPopOver()">Device</span>
<device-popover *ngIf="showPopover"></device-popover>
home.component.ts
onShowPopOver() {
this.showPopover=true;
}
and my devicePopover component looks follows
#ViewChild('myPopover') popover: Popover;
constructor() {
this.popover.show();
}
and my devicePopover.html looks as follows:
<popover-content #myPopover class="myPopover"
title="Add/remove an Emulator"
placement="bottom"
[animation]="true"
[closeOnClickOutside]="true" >
<span>Hello</span>
</popover-content>
device-popover is my selector for devicePopover component. when i try to call the child component it was hitting the constructor but throwing the error as "show of undefined"
#ViewChild refer to a child View, and this view is not created yet when your component is instanciated. You need to rely on a lifecycle hook to be able to access this popover property:
According to the docs :
ngAfterViewInit() Respond after Angular initializes the component's
views and child views.
Called once after the first ngAfterContentChecked().
A component-only hook.
#ViewChild() will get populated just before ngAfterViewInit is called.
You also need to put a template reference on your element if you want to use a string as argument to #ViewChild():
#ViewChild("myPopover")
<div popover #myPopover=popover *ngIf="showPopover"></div>
otherwise you should use a class as argument :
#ViewChild(Popover) //the popover from ngx-popover, not yours
<div popover *ngIf="showPopover"></div>
So this should work :
#ViewChild("myPopover") popover: Popover;
ngAfterViewInit() {
this.popover.show();
}
<div popover #myPopover=popover *ngIf="showPopover"></div>
Related
I am a noob and I am trying to use a react component to attach some listeners to an html div section.
Using the component, I just want to attach listeners to the html div to listen to some events while keeping the appearance and formatting of html the same.
- Is it possible to return html's div from render() of the component?
something like this:
class MyComponent extends React.Component {
...
...
document.getElementById("div_id").addEventListener("drop", this._onDrop.bind(this));
render() { return document.getElementById("div_id"); }
(Above code does not work but I am mentioning it just to give an example of what I am trying to do)
- Is there any other way to apply just the listeners to the html div?
.
What I have tried so far:
Above code gives following error:
Uncaught Error: Objects are not valid as a React child (found: [object HTMLDivElement]). If you meant to render a collection of children, use an array instead.
When I return null in render(), it clears the html section.
render() {return false;}
or
render() {return null;}
I have parent and child component, and have some element to hide and show using <ng-if> by isTrue property value. but currently, facing trouble to do the same.
Exact Scenario:
I have a property called 'isTrue' in parent components controller and passing it to child using isTrue: '<'. Now, in child component, I need to hide something using isTrue property value which I have no issue to do so.
Now. again the cycle repeats the same but this time again I want to hard-reset isTrue in the parent component using isTrueCheck() and again send back to the child component. now, isTrue should set to true and sent it to child component.
Summery:
similarly whenever I call isTrueCheck(), I just want to set 'isTrue' to true and send it to child component.
I have tried to set it into $onInit().
Parent controller:
this.isTrue;
this.isTrueCHeck = function(){
isTrue = true;
};
Child controller:
isTrue: '<'
if (isTrue){
isTrue= false;
}
Child HTML/template
<div ng-click="isTrueCheck"></div>// Calling to reset `isTrue` property
<div ng-if="$ctrl.isTrue">ele1</div>
<div ng-if="!$ctrl.isTrue">ele2</div>
Now, I want to call parent controller and hard reset to true and do the same procedure.
I am not sure I understood your problem.
am I right if I say:
You have a parent component and some children
You have a variable 'isTrue' set in parent and want to propagate it in children. When 'isTrue' changes in the parent, you want to trigger it in children.
Well, if so, in children you need to implement the $onChange method in your children:
isTrue: '<'
the one above is your variable passed from parent.
//
// React to changes of *one-way bindings* (< and #) of a component
// see http://blog.thoughtram.io/angularjs/2016/03/29/exploring-angular-1.5-lifecycle-hooks.html
// see https://toddmotto.com/angular-1-5-lifecycle-hooks#onchanges
ctrl.$onChanges = function (changesObj) {
// if isTrue changes, do something
if (changesObj.isTrue && changesObj.isTrue.currentValue) {
// do something...
// ....
}
}
see: http://blog.thoughtram.io/angularjs/2016/03/29/exploring-angular-1.5-lifecycle-hooks.html
and
https://toddmotto.com/angular-1-5-lifecycle-hooks#onchanges
If your HTML is like below you could do something like this:
<div ng-controller="ParentCtrl">
<div ng-controller="ChildCtrl">
</div>
</div>
Then you can access the parent scope as follows
function ChildCtrl($scope) {
$scope.isTrue= $scope.$parent.isTrue;
}
If you want to access a parent controller from your view you have to do something like this:
<div ng-if="$parent.isTrue">ele1</div>
<div ng-if="!$parent.isTrue">ele2</div>
In child component, I set the props as following:
function mapStateToProps(state) {
return {
user : state.App.get('user'),
foo: 'ok'
}
}
But when I read this.props.children in render method of parent component, foo is not there. Anyone knows why?
I realized that I can't see the child state from a parent in my project. Am I missing something?
I'm also using Redux in this app. Whats wrong? What's the proper way of doing something like this.props.children.foo in parent Component?
You shouldn't be referencing this.props.children.foo to get foo. Once you've connected your component to mapStateToProps, you should be able to reference it just from this.props.foo
this.props.children will retrieve all the elements enclosed within an opening and closing tag of React component.
There is a CodePen example on the React documentation page that illustrates this:
http://codepen.io/gaearon/pen/ozqNOV?editors=0010
function WelcomeDialog() {
return (
<FancyBorder color="blue">
/*everything between these two blocks*/
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
/*is what is sent to FancyBorder as this.props.children*/
</FancyBorder>
);
}
Source: https://facebook.github.io/react/docs/composition-vs-inheritance.html
I'm new to ReactJS. I want to be able to set some properties of a React component and then be able to access it from a parent React component. But I'm not entirely sure how to do this. For example, consider the following two classes:
export default class SubWindow extends React.Component {
click(event)
{
this.myCollection.push({name:'receiptNum',value:$(event.currentTarget).html()});
}
render()
{
return (
<ul>
<li onClick={this.click.bind(this)}>0</li>
<li onClick={this.click.bind(this)}>1</li>
<li onClick={this.click.bind(this)}>2</li>
<li onClick={this.click.bind(this)}>3</li>
</ul>
);
}
}
export default class MainWindow extends React.Component {
click(event)
{
console.log(SubWindow.myCollection);
}
render()
{
const SubWindow = require('./SubWindow').default;
return (
<SubWindow />
<button onClick={this.click}>Log subwindow array</button>
);
}
}
Basically, I want the SubWindow to have a property called myCollection which is just an array of JSON objects. myCollection gets populated by each click on the list item.
Later, I want to be able to console.log(SubWindow.myCollection) when I press on a button in the parent window. My question how do I access the SubWindow.myCollection from a parent react component?
I would recommend you to solve this problem by using callback. MainWindow is creating SubWindow, and you can give here a callback function as a property. For example:
<SubWindow onClick={this.onSubwindowClick} />
Now in your SubWindow class, just call this callback inside your click function:
click(event)
{
this.myCollection.push({name:'receiptNum',value:$(event.currentTarget).html()});
this.props.onClick(/* data you want to pass to the parent */);
}
Also you have to define onSubwindowClick in the class MainWindow. This function should receive any data you wish from child class - the data which you pass from child where I put comment /* data you want to pass to the parent */.
Also, don't forget to bind this to that onSubwindowClick function. This is usually done in constructor of the class, which I suggest you to create for each component.
You can find good example about "passing data to parent" on React's pages. You can take a look at the article Thinking in React, particularly section "Step 5: Add inverse data flow".
just pass a function to you child component, and the function is bind to the parent component's 'this', actually you just created a closure.
then in your parent component, the function's args are passed in your child component, meanwhile your parent component's scope has access to the args, so in the parent scope you can get access to the data in the child scope.
I am passing a component to a nested component a onClick method that modifies the state of the parent component.
Somehow the method is being called when a component (not sure if it's parent or child) is being mounted. And now, I'm getting the following error message:
Uncaught Error: Invariant Violation: setState(...): Cannot update
during an existing state transition (such as within render). Render
methods should be a pure function of props and state.invariant
The code for passing the child looks like the following
var playlists = this.props.data.map(function(playlist) {
return (
<PlaylistItem key={playlist.id}
data={playlist}
showPlaylistCode={this.getPlaylistCodeData}
/>
);
}.bind(this));
In your Playlist Item component, line 20, try changing it to:
<div className="playlistCode i mfi-qr-code" onClick={this.props.showPlaylistCode.bind(this, this.props.data.id)}></div>
When you need to send an argument to a function that's used onClick in React, you need to use bind. As with any use of bind(), the first argument should be the context of this, and the second should be what you want to send to the click handler function.