Trying to check if properties exist with nuxt js - json

Hi i'm just trying to check if {{data.name}} exist.
if not exist just dont show this..
Iterations :
<div v-if="conts.Titre || conts.keys(conts.Titre).length > 0" class="communes-contenu">
<div v-if="conts.Titre != ' '" class="communes-contenu">
<h3 v-if="conts.Titre">{{ conts.Titre }}</h3>
But nothing... just a "Cannot read property 'Titre' of null"
thx !

"Cannot read property 'Titre' of null" means that the object that holds Titre is null
=> conts must be null.
You can add an additional check for the existence of conts in the same v-if, or wrap it around.
Option 1:
<h3 v-if="conts && conts.Titre">{{ conts.Titre }}</h3>
Option 2:
<template v-if="conts">
<h3 v-if="conts.Titre">{{ conts.Titre }}</h3>
</template>

Related

Array of calendars with ViewChildren?

I need to create a dynamic full-calendar array.
The idea is that the user can select one of "n" diaries, relating to different operators, which are shown to him at the same time.
I'm using Angular 9.
Of course... it doesn't seem to work...
My .ts file has this declaration...
#ViewChildren(FullCalendarComponent) fullCalendars: FullCalendarComponent[];
public calendarOptions: CalendarOptions = null;
...and I use the component in this way...
render() {
if (this.fullCalendars && this.fullCalendars.length > 0) {
this.fullCalendars.forEach(fc => fc.getApi().render());
}
}
... and this is the HTML part ...
<div class="card" *ngFor="let ag of agendas; let i = index">
<div class="card-header">
<b>{{ ag.description }}</b>
</div>
<div class="card-body">
<full-calendar #fullCalendars [options]="calendarOptions"> </full-calendar>
</div>
</div>
Is this correct? I'm trying to understand why I'm getting this error...
Cannot read properties of undefined (reading '0')
...but first I need to know if the above code is ok.
Thank you so much!

Having a dash if field values are null

I am working on an angular application. I have following code in my html
<div>{{ data.date | date:'d-MMM-y' || '-' }}</div>
<div>{{ data.id || '-' }}</div>
The problem I am facing is, whenever for any field like date and id, if value coming from API is null then next div shifts upward. I want div to be in that particular place it is when value is not null. So, I want to have a dash "-" whenever a value coming from API is null. So in my code I added a || '-' to all the fields but still it is not working. I am not getting "-" in my html. How can I do that?
You were close to the result, you are just missing some parentheses:
<div>{{ (data?.date) ? (data.date | date:'d-MMM-y') : '-' }}</div>
Working Stackblitz: https://stackblitz.com/edit/angular-vb4peg?file=src/app/app.component.ts
Just comment the line this.data["date"] = new Date(); and you will see how it changes.
You can use on this case the nullish coalescing operator
it will be like:
<div> {{ (data.date | date:'d-MMM-y') ?? '-' }} </div>
<div> {{ data.id ?? '-' }} </div>

Angular - How to display single "no results" message on no results

I'm having trouble coming up with a way to show my "no results" div element. Basically, I have a list component containg order timeline section components, each one of these section contains order components. Like so:
My orders-list.component.html (check bottom div):
<div class="list-container" [ngClass]="{section: isDeliverySlotsActive === false}">
<label class="list-header" *ngIf="isDeliverySlotsActive === true" style="margin-top: 1.625rem">DELIVERY SLOTS ORDERS</label>
<div [ngClass]="{section: isDeliverySlotsActive === true}" *ngFor="let date of timelines">
<app-orders-list-section
[orders]="orders"
[timeline]="date"
[isDeliverySlotsActive]="isDeliverySlotsActive"
[searchTerm]="searchTerm"
></app-orders-list-section>
</div>
</div>
/* I want to show the below div when there are no results for the search */
<div id="no-results">
<img src="../../../assets/my-orders/no-results.png" alt="No Results" style="margin-top: 6.063rem; margin-bottom: 2.837rem;">
<label class="no-results-text">COULDN'T FIND ANYTHING</label>
<label class="no-results-text weight-medium">Search by order number or customer</label>
</div>
For each section, a filtering method is applied when the user searches for an order using the search bar. If the search term does not correspond to an order in a section, the order is not displayed for that section. If there are no results for that section the section header is also not displayed.
My orders-list-section.component.html:
<div *ngIf="filteredSectionOrders.length > 0">
<label
*ngIf="isDeliverySlotsActive === true"
[ngClass]="{ slots: isDeliverySlotsActive === true }">
{{ timeline | addSectionDateFormat }}
</label>
</div>
<div *ngFor="let order of filteredSectionOrders">
<app-orders-list-item
[order]="order"
[timeline]="timeline"
></app-orders-list-item>
</div>
My filter method in the section component:
filterSectionOrders(searchString: string){
if(!searchString) return;
if(this.hasNumbers(searchString)){
this.filteredSectionOrders = this.filteredSectionOrders.filter(order => order.order_num.toString().indexOf(searchString) !== -1);
}
else{
this.filteredSectionOrders = this.filteredSectionOrders.filter(order => {
if(order.first_name && order.last_name){
let fullName = order.first_name + " " + order.last_name;
if(fullName.toLowerCase().indexOf(searchString.toLowerCase()) !== -1){
return order;
}
}
})
}
}
Given that I apply this filter to each section and not to the list as a whole, how can I find out when there are 0 total results so I can show only one (not for each section) div element with a "no results found" message?
Thank you in advance.
You can easily use *ngIf;else link to ngIf from angular inside your HTML
I am not sure where do you use filteredSectionOrders, because it is not shown in your html, but let's assume your app-orders-list-section has some HTML logic where you use *ngFor to loop through orders and show it properly
so, I guess your code looks something like this
<div class="order" *ngFor="let order of filteredSectionOrders">
<img/>
<p>
{{ order.first_name + ' ' + order.last_name }}
</p>
</div>
This is simplified html how I assume it looks like.
What you can do is next:
<ng-template *ngIf="filteredSectionOrders.length > 0; else noResultsBlock">
// here you insert your code to render orders
<div class="order" *ngFor="let order of filteredSectionOrders">
<img/>
<p>
{{ order.first_name + ' ' + order.last_name }}
</p>
</div>
</ng-template>
<ng-template #noResultsBlock>
<p> No results </p>
</ng-template>
So, this would simple solution
If you want to improve it even more, it would be better to have a new variable, lets say areThereResults, which you will set to true or false, at the end of your method filterSectionOrders, based on filterSectionOrders.length. Then, you would use this new variable inside *ngIf check, instead of filterSectionOrders.length > 0.
Reason for using boolean variable instead of using actual array is detection changes, and will anguar re-render UI inside *ngIf. You can read more about it on Angular documentation, just search for detection changes.

How to use "v-if" in Vue.js to render a <span> only if parent div has a specific property?

What I'm trying to do is make it so that <span v-if="spinnerToggle && command-id=='updateAllExternalReferences'">Spin</span> only renders when spinnerToggle has a value of true and the parent div has a command-id property of updateAllExternalReferences.
I've been able to get this to work using only the spinnerToggle conditional, but adding the command-id one causes it to give me the following error:
[Vue warn]: Property or method "id" is not defined on the instance
but referenced during render. Make sure that this property is
reactive, either in the data option, or for class-based components, by
initializing the property.
Does v-if not support conditionals that reference properties in the parent div? If so, how should I implement this sort of functionality? Below you'll find the parent div and the respective <span>.
<div class="tool is-activatable"
v-if="config.isVisibleToUser"
#click="dispatch"
:class="[config.cssClass, {'is-active': active, 'is-highlighted': highlight, 'is-button': !context.reordering}]"
:command-id="config.command"
:context-menu-name="contextMenu.name"
:context-menu-details="contextMenu.contextMenuDetails"
:data-id="config.id"
:disabled="disabled"
:data-placement="inMenu ? 'right-top' : config.tooltipPosition || 'bottom'"
:data-original-title="(config.tooltipKey || config.tooltip || config.toolName) | i18next"
:data-expanded-content="(config.expandedTooltipKey || config.expandedTooltip) | i18next" data-html="true"
:data-expand-delay="inMenu ? 0 : config.expandDelay > -1 ? config.expandDelay : 2000"
:data-trigger="config.tooltipTrigger"
:tooltip-dynamic-snippet-id="dynamicSnippetId">
<img v-if="!hasIcon && config.img" :src="config.img" />
<ToolIcon v-if="hasIcon" :icon="config.icon" :iconUri="config.iconUri" :initials="config.iconInitials"
:awaitingData="false" :updateAvailable="config.isNewerVersionAvailable"/>
<span v-if="spinnerToggle && command-id=='updateAllExternalReferences'">Spin</span>
<span class="tool-label" :class="{'hide-in-toolbar': !shouldShowLabel}">
{{ (config.toolDisplayName || config.toolName) | i18next }}
</span>
<ShortcutKeys v-if="inMenu" :shortcut="shortcut" />
<div v-if="context.reordering" class="drag-handle"></div>
</div>
You can't directly reference the attribute from the parent <div> but you can reference the same data that was used to populate it:
<span v-if="spinnerToggle && config.command === 'updateAllExternalReferences'">Spin</span>
If the command-id expression were more complicated you could refactor to use a computed property rather than duplicating the same logic in both places.

Use local variable in template html without component Angular2+

I want to use a local variable into my html template to use it in css classes but without linking it with the component. I want to do that :
[local_html_variable = 1]
<div class="css-{{ local_html_variable }}">
Div #1
</div>
[local_html_variable + 1]
<div class="css-{{ local_html_variable }}">
Div #2
</div>
[local_html_variable + 1]
<div class="css-{{ local_html_variable }}">
Div #3
</div>
...
to get
<div class="css-1">
Div #1
</div>
<div class="css-2">
Div #2
</div>
<div class="css-3">
Div #3
</div>
...
Important : the number of div is dynamic.
But I don't achieve it. I tried with <ng-template let-localHtmlVariable> but didn't work.. Any idea ?
You can use *ngFor structural directive
<div *ngFor="let value of [1,2,3]" class="css-{{value}}">
DIV #{{value}}
</div>
Here is a very situational answer that takes advantages of truhy/falsy values :
<ng-container *ngIf="1 as i">
Number is {{ i }}
</ng-container>
Use it in your classes in the container itself :
<div class="css-{{ i }}">With interpolation</div>
<div [class]="'css-' + i">With input</div>
Here is the stackblitz : https://stackblitz.com/edit/angular-3wm4en?file=src%2Fapp%2Fapp.component.html
EDIT explanation :
In javascript, every value can be transalted to boolean : they are truthy or falsy values.
The quick boolean parse operator is the !! double negation.
Let's try :
console.log(!!'');
console.log(!!0);
console.log(!!5);
When we use this notation, the evaluation use the same principle : it tests if the given value is truthy or falsy. In numbers, 1 being truthy, the test checks out, and the as i notation simply creates a template variable.
For information, falsy values are 0, '', null, undefined, infinity, NaN.