A component is not receiving any of it's #Input values - javascript

I use Angular 8 and I have 3 components:
CalculationFirst : app-calculation-first
CalculationSecond : app-calculation-second
CalculationThird : app-calculation-third
CalculationFirst is the "parent" component and has CalculationSecond as a "child" in a way that I use CalculationSecond inside html template of CalculationFirst.
So in CalculationFirst.component.html it looks like this:
<div class="container">
<form #f="ngForm" (ngSubmit)="submit()" novalidate *ngIf="settings.isloaded == true">
<div class="row">
<app-calculation-second [elements]="settings.seconds.elements" [epics]="epics"[types]="types" (opendialoglistevent)="openDialogList($event)"></app-calculation-second>
</div>
</form>
</div>
Then CalculationSecond.component.html looks like this:
<div class="col-lg-2 box">
<div class="row">
<div class="row content" *ngFor="let element of elements;">
<div class="col-lg-14">
<app-calculation-third [elem]="element" [types]="types"></app-calculation-third>
</div>
</div>
</div>
</div>
And finally CalculationThird.component.html looks like :
<div class="col-lg-14">
TEST_TEXT_1
{{elem}}
TEST_TEXT_2
</div>
Now, the problem is if I were to just look at my rendered page, only TEST_TEXT_1 page shows, {{elem}} does not render and neither does TEST_TEXT_2. If I am to check the value of elem, it is undefined. I would expect to get an error that I am trying to display undefined, however I do not get anything. My environment.ts is not set to production, so I do not know if my error is not big enough for angular to inform me. (On a tangent, I don't even get an error if I use a json object in an *ngFor instead of an enumerable (Array), but I'm still not sure if I have some lacking setting).
I have also tried, when I use the third component, to not pass the element from *ngFor but to pass a handmade object {'elemId':0}, this had the same result.
If I move :
<app-calculation-third [elem]="element" [types]="types"></app-calculation-third>
to CalculationFirst, making it a direct child, it works perfectly fine, regardless of what I put in there. Is there a limit to the amount of child components you can have? Am I missing something?
*Edit: Also for those who suggested it is the *ngFor or the usage of different variables, I can make CalculationSecond look like the following and still it doesn't work:
<div class="col-lg-2 box">
<div class="row">
<div class="row content" *ngFor="let element of elements;">
<div class="col-lg-14">
</div>
</div>
</div>
<app-calculation-third [elem]="{ elementId: '' }" [types]="types"></app-calculation-third>
</div>

You are passing the elements to seconds input.
[seconds]="settings.seconds.elements"
But you use elements in your app-second-calculation element.

Related

How to create a custom refinement list in vue instant search?

I am working with Laravel Scout and alogolia as the driver. Since I have vue on the front end, I tried the vue instant search package which works really well.
The issue that I am facing is that I need to customize it to the in app styles we are using.
Refinement Section
This is the particular component I am trying to customize. It tried over riding the classes like they show in Styling Section but that won't cut it for me since I need to add more tags and attributes in there.
<ais-refinement-list attribute-name="categories.title" inline-template>
<div class="column w-1/5">
Hello
</div>
</ais-refinement-list>
Now I know I can start to write an inline template like so but what I don't understand yet, is how to get the values for refinements so I can make the checkboxes and furthermore how to send them back to the component once they are selected. Any help is appreciated.
I dug through the package it self here and then found the template inside here. For some reason I could not see this in vendor code.
Got all the variables and method calls from in there
This is the custom version:
<ais-refinement-list attribute-name="categories.title" inline-template>
<div class="column w-1/5">
<h3>Categories</h3>
<hr class="my-3">
<div class='column w-full mb-4' v-for="facet in facetValues">
<div class="checkbox-control mb-4">
<input type="checkbox" :id="facet.name" :value="facet.name" v-model="facet.isRefined" #change="toggleRefinement(facet)"/>
<label :for="facet.name">{{ facet.name }} ({{ facet.count }})</label>
</div>
</div>
</div>
</ais-refinement-list>

Vue Component Reference Error

I made a Vue component that displays a modal to ask the user whether they want to play as 'X' or 'O'. It's supposed to be able to do this by having a v-on:click='startComp('X') - but this isn't working, it's throwing a Reference Error and I have no idea why. Any help would be greatly appreciated, as I've been at this for a few days now...
The reason I am trying to call the function in the first place is because I need the v-on:click to both set this.modal to false (thus removing the modal and transitioning to the 'board') and set this.marker to its respective value. And afaik, you can only set 1 item in a v-on:click.
Here is a forked version of my original Codepen for testing this.
**Edit - Sorry, this thing just flat out will not let me format the code correctly.
<script type="text/x-template" id="modal-template">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-body">
<slot name="body">
<div class='row'>
<div class="col-xs-2 select_marker"
id="SX"
v-on:click='compStart("X")'>X</div>
<div class="col-xs-8 select_title">
SELECT<span style='color:#00B16A'>MARKER</span>
</div>
<div class="col-xs-2 select_marker"
id="SO"
v-on:click='compStart("O")'>O</div>
</div>
</slot>
</div>
</div>
</div>
</div>
</transition>
compStart(marker) {
this.marker = marker;
this.showModal = false;
this.start('comp');
},
So after 3 days of smashing my head against the wall, I finally figured this out. I guess the modal wasn't inside the targetted element for Vue, so instead of v-on:click='compStart("X")' it needed to be v-on:click='game.compStart("X")'.

ng-include: Access child scope issue

I'm using DayPilot Scheduler in my app and i'm having the following issue.
home.html:
<div class="container-fluid">
<daypilot-scheduler id="scheduler" daypilot-config="schedulerConfig" daypilot-events="events"></daypilot-scheduler>
</div>
I access daypilot scheduler in my controller like this:
$scope.scheduler;
This works when daypilot directive is directly inside home.html like in home.html above, but returns undefined when I include daypilot with ng-include:
<div class="container-fluid">
<div ng-include src="'partials/partial1.html'"></div>
</div>
partial1.html:
<section>
<daypilot-scheduler id="scheduler" daypilot-config="schedulerConfig" daypilot-events="events"></daypilot-scheduler>
</section>
If it's included with ng-include, $scope.scheduler returns undefined. scheduler is placed under $$childTail as $$childeTail.scheduler.
What am I doing wrong, and how can I access $$childTail?
Try adding $parent. prefix to id attribute's value. So partial1.html will be:
<section>
<daypilot-scheduler id="$parent.scheduler" daypilot-config="schedulerConfig" daypilot-events="events"></daypilot-scheduler>
</section>
And in controller access it like you always did:
$scope.scheduler;

'Echo' html from string in angularjs when the string is on a template

I am using ionic tinder cards and each new card should be inserted in an predefined array as an object, likewise:
{text: "some_text"}
However, I might be getting html in the string and I want that html to be rendered. How can I do this considering the object above goes to a predefined array, something happens on the ionic code and then I inject it like this?
<div class="card">
{{card.text}}
</div>
use ng-bind-html directive: may be require import the sanitize module
<div class="card">
<span ng-bind-html="card.text"></span>
</div>
You should use ng-bind-html
<div class="card">
<span ng-bind-html="card.text"></span>
</div>
If your HTMl contains potentially dangeorus tag (like script tag), you should sanitize it before

Passing models in AngularJS

I am building my first AngularJS app comming from backbone. I have a list where the user can select an item. The goal is show the details of the selected item in a view below the list. The list-view and detail-view are both part of the main-view.
my list view
<div id="rfc-records" class="container-fluid">
<div ng-repeat="record in records" ng-click="selectRow()" class="row select table-row">
<div class="col-lg-1 center">
{{record.id}}
</div>
<div class="col-lg-1 center">
{{record.rfcObject}}
</div>
<div class="col-lg-5">
{{record.rfcFunction}}
</div>
<div class="col-lg-2">
{{record.status}}
</div>
<div class="col-lg-3">
{{mii.utils.date.extToIntDate(record.firstProcessing)}}
</div>
</div>
</div>
As you see I already added an event to each row: ng-click="selectRow()".
It is unclear to me how to know the selected row in this function. I could do something like this :
ng-click="selectRow(record)
MainController
$scope.selectRow = function(record){
alert(record.id); // undefined
}
The result is undefined so this does not work. Plus this seems like a bad approach to pass the model back from the view to the controller. I might be able to get the application working but I have the feeling that I won't be using the paradigm as intended.
In backbone I would have a seperate view for each row where the model is bound to. But in Angular models aren't as explicit as in backbone.
In general I don't really understand how models work in Angular. R
Regarding this example I have the following questions:
How do I know what item is selected in the list
Where should I put the selectRow function? In the controller of the Mainview or in the list-view directive?
How do I pass the selected model to the details-view.
Well, passing current item into ngClick handler is pretty usual way to solve this task. I'm not sure why it's not working for you, it should. Here is the example of this typical approach.
In backbone I would have a seperate view for each row where the model is bound to. But in Angular models aren't as explicit as in backbone.
Actually Angular is even more elegant in this concern. You still have model available in every iterated row. You can refer current child scope as this in controller. So in your case if you don't want to pass record object into controller function on click, you can use this and it will point to the current scope object (remember that ngRepeat creates new child scope for every row):
$scope.selectRow = function() {
alert(this.record.id);
};
and you don't have to pass anything in HTML:
ng-click="selectRow()"
Demo: http://plnkr.co/edit/kN0vB6N6v7XnqASRSmAd?p=preview
ng-click and ng-repeat are in same div. You can add a new div in this repeated div like and this is works for me :
<div id="rfc-records" class="container-fluid">
<div ng-repeat="record in records" class="row select table-row">
<div class="col-lg-1 center">
Select This item<input type=button ng-click="selectRow(record)">
</div>
<div class="col-lg-1 center">
{{record.id}}
</div>
<div class="col-lg-1 center">
{{record.rfcObject}}
</div>
<div class="col-lg-5">
{{record.rfcFunction}}
</div>
<div class="col-lg-2">
{{record.status}}
</div>
<div class="col-lg-3">
{{mii.utils.date.extToIntDate(record.firstProcessing)}}
</div>
</div>
</div>

Categories

Resources