Bingding data to Kendo Angular Grid - javascript

I am having a small issue with Kendo Grid for Angular.
I'm trying to bind data after fetching but I am getting this error:
ERROR TypeError: Cannot read properties of undefined (reading 'api')
meaning that the this.agGrid.api.setRowData(result.value) is problematic. Here is my code:
public columnDefs = [
{
headerName: 'productTitle',
field: 'productTitle',
sortable: true,
filter: true,
},
{
headerName: 'productDescription',
field: 'productDescription',
sortable: true,
filter: true,
},
];
public rowData$: Observable<Product[]>;
// For accessing the Grid's API
#ViewChild('productGrid') agGrid: AgGridAngular;
// initialize component
ngOnInit() {
this.getProducts();
}
// fetch all producttypes
getProducts(odataQueryString: string = undefined): any {
this.productService
.getAll_Product(odataQueryString)
.subscribe((result: ODataResponse<Product[]>) => {
if (result) {
this.agGrid.api.setRowData(result.value);
}
});
}
HTML
<div class="body flex-grow-1 px-3">
<div class="container-lg">
<div class="row">
<div class="col-lg-12">
<ag-grid-angular
id="productGrid"
style="width: 100%; height: 100%"
class="ag-theme-alpine"
[columnDefs]="columnDefs"
[rowData]="rowData$ | async"
enablecolresize
enablesorting
enablefilter
rowheight="22"
rowselection="multiple"
>
<ag-grid-column
headerName="productTitle"
field="productTitle"
[width]="125"
></ag-grid-column>
<ag-grid-column
headerName="productDescription"
field="productDescription"
[width]="120"
></ag-grid-column>
</ag-grid-angular>
</div>
</div>
</div>
</div>

try adding #productGrid as a directive for the ag-grid-angular html tag. Idk if #ViewChild takes automatically the id attribute.
Also in my projects I have a gridReady event that initializes the gridApi and you might be missing.
HTML:
<ag-grid-angular
#productGrid
id="productGrid"
style="width: 100%; height: 100%"
class="ag-theme-alpine"
[columnDefs]="columnDefs"
[rowData]="rowData$ | async"
enablecolresize
enablesorting
enablefilter
rowheight="22"
rowselection="multiple"
(gridReady)="onGridReady($event)">
TS:
onGridReady(params) {
this.gridApi = params.api;
}
Also try placing a ? after the agGrid variable just to discard any initialize error that may cause the grid to stop working and find out what problem is occurring
if (result) {
this.agGrid?.api.setRowData(result.value);
}

Problem was that the height of the height needed to be in pixels.
<ag-grid-angular
#productGrid
id="productGrid"
style="width: 100%; height: 500px"
class="ag-theme-alpine"
[columnDefs]="columnDefs"
[rowData]="rowData$ | async"
enablecolresize
enablesorting
enablefilter
rowheight="22"
rowselection="multiple"
(gridReady)="onGridReady($event)">

Related

jquery doesn't work correctly when I call data with Fetch in VueJS?

Owlcarousel-slider works fine when I use below code.
HTML Code:
<div class="banner">
<div class="main-banner owl-carousel" id="homeage-data">
<div class="item" v-for="slider in sliders">
<div v-bind:class="slider.class_type"> <img v-bind:src="slider.image_src" alt="Electrro">
<div class="banner-detail">
<div class="container">
<div class="row">
<div class="col-md-3 col-3" v-if="slider.align_right"></div>
<div class="col-md-9 col-8">
<div class="banner-detail-inner">
<span class="slogan">{{ slider.label }}</span>
<h1 class="banner-title" v-html="slider.banner_title"></h1>
<span class="offer">{{ slider.banner_desc }}</span>
</div>
<a class="btn btn-color big" v-bind:href="slider.button_link" v-if="slider.button_np" target="_blank">{{ slider.button_text }}</a>
<a class="btn btn-color big" v-bind:href="slider.button_link" v-else-if="!slider.button_np">{{ slider.button_text }}</a>
</div>
<div class="col-md-3 col-4" v-if="!slider.align_right"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
JavaScript Code:
<script>
new Vue({
el: '#homeage-data',
data: {
sliders: [
{
"label": "Discover",
"banner_title": "Top Branded for <br>headphone",
"banner_desc": "best selling, and popular.",
"image_src": "images/banner1.jpg",
"button_text": "Shop Now!",
"button_link": "#link",
"class_type" : "banner-1",
"button_np": true,
"align_right": false
},
{
"label": "curved tv",
"banner_title": "Get latest TV models",
"banner_desc": "Get the top brands for TV",
"image_src": "images/banner2.jpg",
"button_text": "Shop Now!",
"button_link": "#link",
"class_type" : "banner-2",
"button_np": false,
"align_right": true
},
{
"label": "Premium",
"banner_title": "drone cameras",
"banner_desc": "The latest camera up to 30% off",
"image_src": "images/banner3.jpg",
"button_text": "Shop Now!",
"button_link": "#link",
"class_type" : "banner-3",
"button_np": true,
"align_right": false
}
]
},
});
</script>
Output Image: (Very Nice!)
But when I call the code remotely with Fetch, the image is broken.
JavaScript Code: (I uploaded the slider array to the api.php file and called it remotely.)
<script>
new Vue({
el: '#homeage-data',
data: {
sliders: [
]
},
created() {
fetch("/api/api.php")
.then((response) => { return response.json() })
.then((response) => {
this.sliders = response.sliders;
});
}
});
</script>
Output Image:
As I understand it, it cannot render JQuery code because it was added later.
No matter what I did, I couldn't find the right way.
I have not tried the code below. It didn't happen :(
<script>
new Vue({
el: '#homeage-data',
data: {
sliders: [
]
},
created() {
fetch("/api/api.php")
.then((response) => { return response.json() })
.then((response) => {
this.sliders = response.sliders;
});
$(".main-banner, #client").owlCarousel({
//navigation : true, Show next and prev buttons
items: 1,
nav: true,
slideSpeed : 300,
paginationSpeed : 400,
loop:true,
autoPlay: false,
dots: true,
singleItem:true,
nav:true
});
}
});
</script>
Demo of using VueOwlCarousel in Vue2, without npm:
Vue.use(VueOwlCarousel);
new Vue({
el: '#app',
data: () => ({
slides: 0,
options: {
autoplay: true,
autoplaySpeed: 800,
autoplayTimeout: 1800,
lazyLoad: true,
autoplayHoverPause: true
}
}),
mounted() {
setTimeout(() => {
this.slides = 7
}, 2000)
},
})
div.owl-carousel {
width: 400px;
height: 180px;
}
.owl-stage-outer {
height: 111px;
}
.loader {
height: 180px;
display: flex;
align-items: center;
width: 400px;
justify-content: center;
}
h2 {
color: #ddd;
}
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
margin: 0;
}
<script src="https://v2.vuejs.org/js/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-owl-carousel#2.0.3/dist/vue-owl-carousel.min.js"></script>
<div id="app">
<vue-owl-carousel :items="1"
v-if="slides"
v-bind="options">
<img v-for="s in slides"
:key="s"
:src="`https://placeimg.com/400/111/any?${s}`">
</vue-owl-carousel>
<div v-else class="loader">
<h2>Loading...</h2>
</div>
</div>
Personal advice: do not mix jQuery with Vue. You only want one source of truth for your DOM manipulations.
That's the underlying cause of your issue.
Note: Owl carousel can't be initialised with empty slides. For this reason, I've placed a v-if="slides" (or, if slides would have been an array, v-if="slides.length").
Also note Owl takes control over the carousel DOM element and, from that moment on, even if you change the slides array, it won't react to the change. If you wanted to update the slides, you'd need the owl instance, change its internal slides (which are built from the original DOM) and then call its internal .refresh() method.

how to get the size of an ion-col in angular 8

I'm trying to get the ion-col size in angular 8
My code works very well if I want the size of a <div> but doesn't work if I want from <ion-col>.
I get this error message:
ERROR TypeError: Cannot read property 'offsetWidth' of undefined
Someone have an idea if it's possible to do it and how to do ?
Thanks you very much for help
CSS Code:
div {
margin: auto;
height: 50px;
border: 1px solid black;
}
TS Code:
#ViewChild('container', { static: true }) container: ElementRef;
getInfo() {
const width = this.container.nativeElement.offsetWidth;
const height = this.container.nativeElement.offsetHeight;
console.log('width : ', width, ' + ', height);
}
HTML Code:
<ion-content>
<ion-grid>
<ion-row>
<ion-col size="6" (click)="getInfo()" #container>
<div></div>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
That's because <ion-col> is not a ElementRef
You should have something like :
#ViewChild('container', {read: ElementRef}) container: ElementRef;
And then :
this.container.nativeElement.offsetHeight
this work for me in ionic 5
TS CODE
#ViewChild('container', {read: ElementRef}) container: ElementRef;
getInfo() {
const width = this.container.el.offsetWidth; // instead of this.container.nativeElement.offsetWidth;
const height = this.container.el.offsetHeight;
console.log('width : ', width, ' + ', height);
}
HTML CODE
<ion-row>
<ion-col size="12" #container>
.....
</ion-col>
</ion-row>

Showing dynamic text in spinner angular material

I have a spinner , but I also want some text in the spinner independent of the component. So for example if you are doing a save action, then the spinner will showing: ...saving. But for example if you do a search action. The spinner will showing: ..processing and so on.
I have this as spinner component:
<div *ngIf="(isLoading | async)" class="overlay">
<div>
<mat-progress-spinner class="spinner" [color]="color" [mode]="mode" [value]="value"> </mat-progress-spinner>
<div style="position:relative; top: -60px; left: 30px;">{{message}}</div>
</div>
</div>
and ts script:
export class LoaderComponent {
color = 'primary';
mode = 'indeterminate';
value = 50;
message = 'Hello there';
isLoading: Subject<boolean> = this.loaderService.loaderState;
constructor(private loaderService: LoaderService) {}
}
and then for example I load the spinner in this component: listComponent
<app-loader ></app-loader>
So I see the spinner but not the message.
So what I have to improve so that the text will also been shown?
And how to make the text dynamically? So that you can put any text message in it?
Thank you
I have it now like this:
<div *ngIf="(isLoading | async)" class="overlay">
<div>
<mat-progress-spinner class="spinner" [color]="color" [mode]="mode" [value]="value"> </mat-progress-spinner>
<div style="position:absolute; top: -60px; left: 30px;">{{message}}</div>
</div>
</div>
export class LoaderComponent {
color = 'primary';
mode = 'indeterminate';
value = 50;
#Input()
message = 'Hello there';
isLoading: Subject<boolean> = this.loaderService.loaderState;
constructor(private loaderService: LoaderService) {}
}
and this is the css:
.overlay {
position:fixed;
display:block;
width:100%;
height:100%;
top:0;
left:0;
background-color:rgba(74,74,74,.8);
z-index:99999;
}
.spinner {
margin:auto;
position:absolute;
top:50%;
left:50%;
transform: translate(-50%,-50%);
}
You can find Working demo here in this StackBlitz Link
You have to use Behavior Subject and service...
Your app.component.html is..
<mat-toolbar color="primary">Spinner Demo</mat-toolbar>
<div style="margin:1em">
<button style="margin:1rem" mat-raised-button color="primary" (click)="spinner('search')">Search</button>
<button mat-raised-button color="primary" (click)="spinner('Send')">Send</button>
<button style="margin:1rem" mat-raised-button color="primary" (click)="spinner('Save')">Save</button>
</div>
<app-search-output ></app-search-output>
Your app.component.ts is...
export class AppComponent {
constructor( private serachService: SearchService){
}
spinner(term){
this.serachService.sendData(term);
}
ngOnInit(){
}
}
Your Service where you can use behaviorSubject as like this...
export class SearchService {
searchData$: BehaviorSubject<object[]> = new BehaviorSubject<object[]>([{}]);
constructor() { }
sendData(term){
this.searchData$.next(term)
}
getData(){
return this.searchData$.asObservable();
}
}
Your spinner component HTML is...
<div style="margin:2em auto; padding:1rem; box-shadow: 1px 2px 7px red; width:50vw">
<span style="margin:1em; padding:1rem">{{bookData$ |async |json}}</span>
<mat-spinner style="margin:1em" color="warn" ></mat-spinner>
</div>
Your spinner.component.ts is ...
export class SearchOutputComponent implements OnInit {
bookData$;
constructor(private searchService: SearchService) { }
ngOnInit() {
this.bookData$ = this.searchService.getData();
}
}
You can pass text values as #Input to your component and use the component as below
I believe you are not able to see it because of css issue. Try making the text position:absolute.
<div *ngIf="(isLoading | async)" class="overlay">
<div>
<mat-progress-spinner class="spinner" [color]="color" [mode]="mode" [value]="value"> </mat-progress-spinner>
<div style="position:absolute; top: -60px; left: 30px;">{{message}}</div>
</div>
</div>
To further debug please create a stackblitz.
<app-loader [message] = "Processing"></app-loader>
Spinner Component
import { Component, Input, OnInit } from '#angular/core';
export class LoaderComponent {
color = 'primary';
mode = 'indeterminate';
value = 50;
#Input()
message = 'Hello there'; // Default text will be Hello there but if you pass anything as stated above then it will be replaced.
isLoading: Subject<boolean> = this.loaderService.loaderState;
constructor(private loaderService: LoaderService) {}
}
Try to change style position to relative in your html file it should work:
HTML file
<div *ngIf="(isLoading | async)" class="overlay">
<div>
<mat-progress-spinner class="spinner" [color]="color" [mode]="mode" [value]="value"> </mat-progress-spinner>
<div style="position:relative; top: -60px; left: 30px;">{{message}}
</div>
</div>
</div>
TS file
export class ProgressSpinnerOverviewExample {
color = 'primary';
mode = 'indeterminate';
value = 50;
#Input()
message = 'Hello';
isLoading = true;
constructor() {}
}

Custom Component in Vue 2

I created a custom component and registered it. But I get in the browser a warning, which I cannot process. In my opinion it is properly registered?
vue.js:435 [Vue warn]: Unknown custom element: - did you
register the component correctly? For recursive components, make sure
to provide the "name" option.
found in
--->
Main
import GISView from './components/GISView.vue';
import VueEvents from 'vue-events';
window.Vue = Vue;
Vue.use(VueEvents)
var App = window.App = new Vue({
el: '#app',
components: {
'gisview': GISView
},
data() {
return {
eventData: {
foo: 'baz'
}
}
},
methods: {
init: function() {
this.$events.$emit("test", this.eventData);
}
}
});
Component
<template>
<div ref="map" id="map" class="google-map" style="position: relative; overflow: hidden;">
<div style="height: 100%; width: 100%; position: absolute; top: 0px; left: 0px;">
<gisview></gisview>
</div>
</div>
</template>
<script>
import GoogleMaps from '../mixins/GoogleMaps.js';
export default {
mixins: [GoogleMaps],
mounted() {
console.log("Mounted");
this.$events.$on('test', eventData => console.log("Fired"));
},
data: function() {
return {
eventData: {
foo: 'baz'
}
}
},
methods: {
initMap: function() {
map = new google.maps.Map(this.$els.map, {
center: {lat: -34.397, lng: 150.644},
zoom: 8
});
}
}
}
</script>
Usage
<div class="wrapper wrapper-content animated fadeInRight">
<div id="app">
<div class="row">
<div class="col-md-7">
<div class="ibox">
<div class="ibox-title">GIS</div>
<div class="ibox-content">
<gisview></gisview>
</div>
</div>
</div>
</div>
</div>
</div>
I see 1-2 problems here.
You registered GISView to App.vue locally, meaning you can only use <gisview> inside App.vue's template. You can register GISView globally, like so, but i doubt you would want that.
Vue.component(GISView)
Is your second code example supposed to be GISView.vue? If it is, you're trying to use <gisview> within itself. Recursive components are a thing, but i don't think that's what you're going for here.

I created a sorting tool with Angular.js. How can I animate ng-click to create animated transitions when the items are sorted?

I am building a personal portfolio site with Angular and decided to build my project sorter using pure Angular, instead of doing it with jQuery. I utilized the filter feature of Angular, and am able to get the projects to sort correctly. However, when I'm going through the ng-animate section, there's no support for ng-click and filters that I can see. I was also not able to get the ng-animate to work on the ng-repeat (when the projects are all displayed.) I basically want cool transitions whenever a new filter is selected. The same type of reactions to clicking a button as what happens here.
https://mixitup.kunkalabs.com/
What would be the best course of action to handle animating those types of things? Also, does my code look properly done the 'Angular' way?
jsfiddle-
http://jsfiddle.net/jtbitt/tg6oh0g1/6/
HTML -
<div id="portfolio" ng-controller="mainController as main">
<div class="container">
<div class="row">
<div>Portfolio</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="">
<ul ng-repeat="language in main.languages">
<li><button ng-click="main.projectSort(language)">{{ language.name }}</button></li>
</ul>
</div>
</div>
</div>
<div class="row">
<div ng-repeat="project in main.projectsToShow">
<div class="portfolio-projects language-{{ project.reference }}">{{ project.name }}</div>
</div>
</div>
</div>
</div>
CSS -
#portfolio {
height: 100%;
width: 100%;
font-color: black;
}
#portfolio .container, #portfolio .container .row {
height: 100%;
width: 100%;
}
#portfolio .container .row {
height: 33.3%;
}
.portfolio-projects{
border-style: solid;
border-color: #000000;
padding: 10px;
margin: 10px;
}
.language-angular {
color: blue;
}
.language-ruby {
color: red;
}
.language-node {
color: green;
}
JS -
var app = angular.module('portfolioSorter', []);
app.controller('mainController', ['filterFilter', function(filterFilter) {
var vm = this;
vm.languages = [
{
name: 'ALL',
reference: 'all'
},
{
name: 'ANGULAR',
reference: 'angular'
},
{
name: 'NODE',
reference: 'node'
},
{
name: 'RUBY ON RAILS',
reference: 'ruby'
}
];
vm.projects = [
{
name: 'Tic-Tac-Toe',
language: 'ANGULAR.JS',
reference: 'angular'
},
{
name: 'Escrow',
language: 'RUBY ON RAILS',
reference: 'ruby'
},
{
name: 'Feed.Me',
language: 'RUBY ON RAILS',
reference: 'ruby'
},
{
name: 'Gone-In',
language: 'NODE.JS',
reference: 'node'
}
];
vm.projectsToShow = vm.projects;
vm.projectSort = function(language) {
vm.projectsToShow = vm.projects;
switch (language.reference) {
case 'all':
vm.projectsToShow;
break;
case 'angular':
vm.projectsToShow = filterFilter(vm.projectsToShow, 'angular');
break;
case 'node':
vm.projectsToShow = filterFilter(vm.projectsToShow, 'node');
break;
case 'ruby':
vm.projectsToShow = filterFilter(vm.projectsToShow, 'ruby');
break;
default:
vm.projectsToShow;
};
};
}]);

Categories

Resources