Receiving error using ngFor and ngIf in Angulsrjs2 and Ionic 2 - javascript

JoinedArray is an array with some values.
I have to check if the event.listDetails.accessId is present there in the array or not . If accessId is not there in the array then the event-card should not print
<ion-list *ngSwitchCase="'joined'">
<event-card *ngIf="event.listDetails.accessId in joinedArray " ></event-card>
</ion-list>
error is:
EXCEPTION: Error: Uncaught (in promise): Template parse errors:
Property binding ngIfIn not used by any directive on an embedded
template. Make sure that the property name is spelled correctly and
all directives are listed in the "directives" section. ("e keys and i
have to check if it is present in the array or not ..please
suggest-->-->
[ERROR ->]
"): EventListComponent#31:12

Instead of including that logic in your view, you could just create a property in the component like this:
public showCard: bool;
// In the constructor or somewhere else
//...
this.showCard = joinedArray.indexOf(event.listDetails.accessId) > -1;
// ...
And then in the view:
<ion-list *ngSwitchCase="'joined'">
<event-card *ngIf="showCard"></event-card>
</ion-list>
That way we keep things simple, the view just takes care of showing or hiding things, and the component code decides whether if that should be shown or not.
Please also notice that I've used the indexOf() (Reference) method to see if the array contains that value.

Related

SAPUI5 ODataV4 bindAggregation for SmartVariantManagementUi2--Title

I am currently trying to bind my SmartVariantManagementUi2 Control within my sap.ui.comp.filterbar.FilterBar to a Backend-Object: "/Variants>VariantName". Since I don't know how to access the variantmanagement control Within my Filterbar in the view-:
<filterbar:FilterBar id="_worklistFilterbar" persistencyKey="worklistView>/Variants" search="_onLoadFilters">
<filterbar:filterGroupItems>
...
</filterbar:filterGroupItems>
</filterbar:FilterBar >
i am now attempting to bind the VariantItems in the Controller like this:
let oControl = new sap.m.Title({text:"{VariantName}"});
this.byId("_worklistFilterbar")._oVariantManagement.oVariantText.bindAggregation("content", {
path: "/Variants",
template: oControl,
templateShareable: false
});
the binding results in following errors:
Assertion failed: multiple aggregates defined for aggregation with cardinality 0..1
Binding of single aggregation "content" of Element sap.m.Title#application-[appname]-display-component---worklist--_worklistFilterbar-variantUi2-text is not supported! -
Assertion failed: "Element sap.m.Title#__title0-application-[appname]-display-component---worklist--_worklistFilterbar-variantUi2-text-0" is not valid for aggregation "content" of Element sap.m.Title#application-MORe-display-component---worklist--_worklistFilterbar-variantUi2-text
adding element with duplicate id '__title0-application-[appname]-display-component---worklist--_worklistFilterbar-variantUi2-text-0' -
In the rendered app, I can see that the variantItems seem to be bound incorrectly:
If any of you could help me set a correct binding for my variantManagement(-items) within the filterbar or could offer a hint how to access the variantmanagement control in the filterbar-view, it would help me out a lot!
Thx in advance.

Vue-multiselect: How to convert object to array for use in options prop?

I am using vue-multiselect like so:
<multiselect
id="customer_last_name_input"
v-model="value"
:options="activeUserProfiles"
label="lastname"
placeholder="Select or search for an existing customer"
track-by="uid"
:close-on-select="true"
#select="onSelect"
#remove="onRemove"
:loading="isLoading"
:custom-label="customerSelectName"
aria-describedby="searchHelpBlock"
selectLabel=""
>
...that grabs the list of active customers from an Array and then makes them available in a nice select menu.
This works good. However, I need to add another option from another resource (called customerNone) to the options prop and but the data is returned as an Object like so:
{"uid":1,"lastname":"None Given","firstname":"User","email":null,"phone":null...blah}
The vue-multiselect docs state that the :option prop MUST be an Array.
Question: What is the best way for me to handle this in the vue-multiselect component? Here's my attempt to help explain what I am trying to do (not sure if this is the best way to handle it). Unfortunately, my attempt causes a console error (see below):
I am passing a prop down called noCustomer which, if is true, I need to use customerNone profile on :options:
<multiselect
:options="noCustomer ? customerNone : getActiveUserProfiles"
>
here's the error:
Invalid prop: type check failed for prop "options". Expected Array, got Object
Is there a way I can convert the customerNone object to an array of object? Thanks!
You could wrap the customerNone object in brackets at the time that you pass it to the <multiselect> like [customerNone].
This syntax creates a new array on the fly, having 1 element that is the object variable:
<multiselect
:options="noCustomer ? [customerNone] : getActiveUserProfiles"
>
Update for comments
In order to auto-select the generic option when it's available, use a watch on the noCustomer prop to set value whenever noCustomer === true:
watch: {
noCustomer(newValue, oldValue) {
if(newValue) { // Checking that `noCustomer === true`
this.value = this.customerNone;
}
}
}

ERROR TypeError: Cannot read property 'list' of undefined

Getting the error as mentioned when I am trying to get the response from API call and display the information in the response object in the template.
ERROR TypeError: Cannot read property 'list' of undefined.
In service.ts, I am making a server call. I am using OpenWeatherMap API.
getDetails(cityName, countryCd): Observable<any>{
return this.httpclient.get(`${this.url}${cityName},${countryCd}&APPID=${this.apiKey}`);
}
Object format returned by the API:
{"city":{"id":1851632,"name":"Shuzenji",
"coord":{"lon":138.933334,"lat":34.966671},
"country":"JP",
"cod":"200",
"message":0.0045,
"cnt":38,
"list":[{
"dt":1406106000,
"main":{
"temp":298.77,
"temp_min":298.77,
"temp_max":298.774,
"pressure":1005.93,
"sea_level":1018.18,
"grnd_level":1005.93,
"humidity":87,
"temp_kf":0.26},
"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],
"clouds":{"all":88},
"wind":{"speed":5.71,"deg":229.501},
"sys":{"pod":"d"},
"dt_txt":"2014-07-23 09:00:00"}
]}
In home.component.ts, I am subscribing to the service API call. I am getting the reposnse which is of type 'object'.
I have an array of objects called cities. I am loading the response object from the server as one of the property in each object of the array cities.
this.cities = this.cityService.getCities().slice();
this.cities.forEach(element => {
this.weatherService.getDetails(element.cityName, element.countryCd).subscribe(response => {
element['cityWeather'] = response;});
});
In home.component.html, I am iterating this cities array and the using the response data from the API. The data is displayed properly without any issues.
But in the console I am seeing an error for every iteration of cities array -
ERROR TypeError: Cannot read property 'list' of undefined.
<div class="col-md-4" *ngFor="let city of cities; let i = index">
<span>{{city.cityWeather.list[0].main.temp | kelvinToCelcius}} ℃</span>
<span>{{city.cityWeather.list[0].wind.speed | mtrPersecToKmPerhr}} km/h</span>
</div>
I am relatively new to Angular, need to know what is this error about and how this can be resolved.
Your issue is that in your home component you refer to
<span>{{city.cityWeather.list[0].main.temp | kelvinToCelcius}} ℃</span>
<span>{{city.cityWeather.list[0].wind.speed | mtrPersecToKmPerhr}} km/h</span>
These values may not be defined at all times, so if city.cityWeather is undefined, accessing the .list property would result in the error
Cannot read property 'list' of undefined.
You can fix this by using the Angular safe navigation operator (also known as the Elvis operator).
The Angular safe navigation operator (?.) is a fluent and convenient way to guard against null and undefined values in property paths
-- Angular docs
By changing . to ?., Angular will not throw an error if it can't find the property on the object.
Note that this only works in component templates, and not in TypeScript files.
You can either use The Angular
safe navigation operator (?.)
city.cityWeather?.list[0]?.main.temp
city.cityWeather?.list[0]?.wind.speed
or you can try using Angular async pipe
https://angular.io/api/common/AsyncPipe
Try to change your code like this:
<div class="col-md-4" *ngFor="let city of cities; let i = index">
<span>{{city?.cityWeather?.list[0]?.main?.temp | kelvinToCelcius}} ℃</span>
<span>{{city?.cityWeather?.list[0]?.wind?.speed | mtrPersecToKmPerhr}} km/h</span>
</div>
This may be due the fact that your getCities() request is completed and your getDetails() call is yet to return response which it will give at some point in time due to the asynchronous nature of code. So when the loop execute cityWeather is not available and you get the error. The ? will not throw error but instead it will show data when it will be available.

Angular ng-select : selectedItems.map is not a function

When I'm using ng-select in reactive form angular I get this error:
ERROR TypeError: selectedItems.map is not a function
I have 3 select the first two work very well but in this third one I get the error ! to map item i'm using the function (the ng-select is inside *ngFor) :
//for mappinig item :
mapLabelValueBS(objet) {
return objet.map(data => {
return {
id: data,
text: data.name
}
})
}
//this is the one that is causing the problem
<ng-select
[allowClear]="true"
[items]="mapLabelValueBS(filieres)"
placeholder="Filière non sélectionné"
(selected)="selecteFiliere($event)"
formControlName="filiere">
</ng-select>
the result in my page (when I click on the field it doubles itself) :
Without the code is difficult to know, but today I had the same error. The reason was that I determined a default value in the FormControl that had no relation with the array that ng-select demands. When the FormGroup loaded, and this mistaken default was loaded into the ng-select, the error was selectedItems.map is not a function
This error came while I was passing [items]="value" where the value was not an array, so please check if you are not passing non array element to items binding.
You are trying to bind the items of object type. [items] attribute accepts an array. You can trying adding a pipe keyvalue
<ng-select
[allowClear]="true"
[items]="jsonData | keyvalue"
placeholder="Filière non sélectionné"
(selected)="selecteFiliere($event)"
formControlName="filiere">
</ng-select>
few days ago i came across this error if you are binding a list that is filled from backend server be sure to fill the list using concat method like this
this.userService.getLookup().subscribe((res: any) => {
this.apps = this.apps.concat(res.data);
});
I had same problem, because the list of items was undefined sometime in the middle of page preparing, so I added a silly condition to show those select only when the list of items is ready:
<ng-select
*ngIf="selectedItems.map"
[allowClear]="true"
[items]="jsonData | keyvalue"
placeholder="Filière non sélectionné"
(selected)="selecteFiliere($event)"
formControlName="filiere">
</ng-select>

How to show TypeScript object in HTML (Ionic/Firebase/Angular)

How do I display an object in my HTML file? (Using Ionic) It seems fairly simple, but it won't work. I retrieve the object like this, from a snapshot of my database path:
this.userPath.subscribe(snapshots => {
this.snapshotValue = snapshots.val()
console.log(this.snapshotValue);
})
And the console looks something like this:
http://i.imgur.com/Kk0A6n5.png (I don't have 'reputation' to post images)
I feel like I've tried everything. Like:
<h1>{{snapshotValue}}</h1> //this returns "[object object]"
<h1>{{snapshotValue.navn}}</h1> //this gives me an error: "cannot read property navn of undefined"
<h1>{{snapshotValue[0]}}</h1> //this gives me an error: "cannot read property '0' of undefined.
How do I get the individual values from this object?
you want to use the async pipe with the elvis operator (?) for observables. Below is using just the elvis.
<h1>{{snapshotValue?.navn}}</h1>
The elvis operator checks if the object exists before checking for a property on the object.
In the future instead of using this
this.userPath.subscribe(snapshots => {
this.snapshotValue = snapshots.val()
console.log(this.snapshotValue);
})
you can do
<h1>{{(userPath | async)?.navn}}</h1>
https://angular.io/api/common/AsyncPipe
The async pipe does the subscribe and gets the latest value for you
This happens when you try to render the view before the data is available.Try the following method
In your component declare a boolean variable
private isDataAvailable:boolean=false;
And in your subscribe method make this true once the data is available
this.userPath.subscribe(snapshots => {
this.snapshotValue = snapshots.val()
console.log(this.snapshotValue);
this.isDataAvailable=true;
})
And reneder the template once the data is available using *ngIf
<div *ngIf="isDataAvailable">
<h1>{{snapshotValue}}</h1>
<h1>{{snapshotValue.navn}}</h1>
<h1>{{snapshotValue[0]}}</h1>
</div>
This should do the trick.You can also use async pipe for the same.Find docs here
<h1>{{snapshotValue | json}}</h1> // this should return you a { stringified json }

Categories

Resources