Ionic 4 - Camera - Runtime Error - Object(...) is not a function - object

I'm creating an Ionic app with camera function. I used for this the doc from ionic-framework Ionic native camera
But I get an error when I tried to display the app on my Android device and click onto the "Take a Picture" button.
Error
"Runtime Error Object(…) is not a function"
"TypeError: Object(…) is not a function at Camera.getPicture"
home.ts
import { Component } from '#angular/core';
import { NavController, PopoverController, ViewController } from 'ionic-angular';
import { UserServiceProvider } from './../../providers/user-service/user-service';
import { Camera, CameraOptions, DestinationType, EncodingType, MediaType } from '#ionic-native/camera/ngx';
#Component({
selector: 'page-home',
templateUrl: 'home.html',
})
export class HomePage {
constructor(public navCtrl: NavController, public popoverCtrl: PopoverController, private camera:Camera) {}
myPhoto:any=''
takePicture(){
const options: CameraOptions = {
quality:100,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options).then((imageData)=>{
this.myPhoto=(<any>window).Ionic.WebView.convertFileSrc(imageData);
}, (err) => {
// Error log
});
}
openMoreSetting(event) {
let popover = this.popoverCtrl.create(PopoverPage);
popover.present({
ev: event
});
}
}
#Component({
template: `
<ion-list>
<button ion-item>Menu für Settings</button>
</ion-list>
`
})
export class PopoverPage {
constructor(private userServiceProvider: UserServiceProvider,
private viewCtrl: ViewController) {
}
close() {
this.viewCtrl.dismiss();
}
}

Related

How can i asynchronouslycall this service function in another component? Angular 11

I have an async function getIdentByInfo and in the console i get the right output if i log it in this function. As soon as i call it in another component it doesnt work and i only get 'undefined'. I know it has something to do with beeing ssynchrone and Promises but i cant figure out how to solve my issue. I need the Model class filled with attributes coming from the http request in another component to send them to another service
import { EventEmitter, Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { IdentModel } from "../models/identmodel.model";
import { IdentteilComponent } from "../pages/identteil/identteil.component";
#Injectable({
providedIn: 'root',
})
export class InfoWebservice {
url = 'http://localhost:4201';
ident: IdentModel[];
constructor(private http: HttpClient) { }
// promise vom typ IdentModel zurückgeben
getIdentByInfo(id: string, vwk: string) {
this.http.get(this.url).toPromise().then(data => {
for (let i in data){
this.ident.push(data[i])
if ( this.ident[i].identNr == id && this.ident[i].vwk == vwk){
return this.ident[i];
}
}
});
}
}
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { InfoWebservice } from '../../webservices/info.webservice'
import { ImageWebservice } from '../../webservices/image.webservice'
import { IdentModel } from "../../models/identmodel.model";
#Component({
selector: 'app-identteil',
templateUrl: './identteil.component.html',
styleUrls: ['./identteil.component.scss']
})
export class IdentteilComponent implements OnInit {
ident = [];
identNr:string;
vwk:string;
imgFrontLink:string;
imgBackLink:string;
constructor(private router: Router, private service: InfoWebservice, private image: ImageWebservice) { }
getIdentNr() : string {
var split = this.router.url.split("/");
this.identNr = split[2];
return this.identNr;
}
//return type is STRING
getVwk() {
// output von window.location.host = repapp-maw.dbl.de
// var splitHost = window.location.host.split(".");
var splitHost = 'repapp-maw';
var splitV = splitHost.split("-");
this.vwk = splitV[1];
return this.vwk;
}
callInfoService = async () => {
return await this.service.getIdentByInfo(this.getIdentNr(), this.getVwk());
}
ngOnInit() {
console.log(this.callInfoService());
}
}
When you use angular, its always preferred not to use await/Promise. Angular has an in-built RX-JS library which has tonnes of super-awesome functionalities that you can use.
For Example, in your case, you can do something like this:
// Your Service File can make use of 'Behavior Subject'
// Please read more about it here: https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject
import { EventEmitter, Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { IdentModel } from "../models/identmodel.model";
import { IdentteilComponent } from "../pages/identteil/identteil.component";
#Injectable({
providedIn: 'root',
})
export class InfoWebservice {
url = 'http://localhost:4201';
ident: IdentModel[];
initialIdentValues: IdentModel = [];
private identSource: BehaviorSubject<IdentModel[]> = new BehaviorSubject<IdentModel[]>(this.initialIdentValues);
public identValuesObs$: Observable<IdentModel[]> = this.identSource.asObservable();
// Create a method to set the values in component-1
setIdentValues(identValues: IdentModel[]) {
this.identSource.next(identValues);
}
// Create a method to return values in component-2 or any component
returnIdentValues() {
return this.identValuesObs$;
}
constructor(private http: HttpClient) { }
// Change your service call to this:
getIdentByInfo(id: string, vwk: string): Observable<any> {
return this.http.get(this.url);
}
}
Now in your component-1 where you want to set the values of this identvalues:
// Component-1
constructor(private infoWebService: InfoWebService){}
// Create a method where you get the values
someMethod() {
// Call the API method here and subscribe and then set the values
this.infoWebService.getIdentInfoById(id, vwk).subscribe((data: any) => {
// Your logic goes here ANDD
if (data) {
for (let i in data){
this.ident.push(data[i])
let localIdentsWithRequiredLogic = [];
if ( this.ident[i].identNr == id && this.ident[i].vwk == vwk){
localIdentsWithRequiredLogic.push(this.ident[i]);
}
// THIS IS IMPORTANT
this.infoWebService.setIdentValues(localIdentsWithRequiredLogic);
}
}
})
}
Then in component-2 or whatever component you want, you can retrieve it using the returnIdentValues method like this:
// In component-2
inSomeMethodWhereYouRequireIdentValues() {
this.infoWebService.returnIdentValues().subscribe(data => {
console.log(data) // this is data that you set in component one
})
}

Angular 7 / Material DataTable not updating after any operation

I'm building an Angular 7 application using #angular/material. When I load the application for the first time, the Datatable renders correctly, but when I call any function, example - delUser, after deleting a user from the database, it's meant to render the table immediately, but it doesn't until I refresh the whole page. I've tried everything, but to no avail.
Here's my code:
import { Component, OnInit, ViewChild, TemplateRef } from '#angular/core';
import { UserService } from 'src/app/services/user.service';
import { MatTableDataSource } from '#angular/material/table';
import { MatSort } from '#angular/material/sort';
import { MatPaginator } from '#angular/material/paginator';
#Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
pgtitle:string = "Manage Users";
dataSource:any;
displayedColumns:string[] = ['userName','email','roleId','userType','Actions'];
#ViewChild(MatSort, {static: true}) sort: MatSort;
#ViewChild(MatPaginator) paginator: MatPaginator;
constructor(
private service:UserService
){}
ngOnInit(): void {
this.getAllUsers();
}
applyFilter(filterValue:String){
this.dataSource.filter = filterValue.trim().toLowerCase();
}
getAllUsers(){
this.service.getAllUsers().subscribe( result => {
this.dataSource = new MatTableDataSource(result);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
});
}
delUser(id){
this.service.deleteUser(id).subscribe(result => {
this.getAllUsers();
});
}
Maybe you can try this:
this.service.getAllUsers().subscribe( result => {
this.dataSource = null; //add this
this.dataSource = new MatTableDataSource(result);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
});

Ionic app does not display anything

I have built a simple ionic app based on the following tutorial: Building a Review app with Ionic 2, MongoDB and Node by Josh Moroney. Whenever I execute the ionic serve command, the app runs in the browser, with no errors, but it displays nothing. Not even the UI elements of the app, just a plain blank screen.
Below are my codes - app.module.ts
import { NgModule } from '#angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { AddReviewPage } from '../pages/add-review/add-review'
import { ReviewsProvider } from '../providers/reviews/reviews';
#NgModule({
declarations: [
MyApp,
HomePage,
AddReviewPage
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
AddReviewPage
],
providers: [
ReviewsProvider
]
})
export class AppModule {}
Provider - reviews.ts
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Injectable } from '#angular/core';
import 'rxjs/add/operator/map';
/*
Generated class for the ReviewsProvider provider.
See https://angular.io/guide/dependency-injection for more info on providers
and Angular DI.
*/
#Injectable()
export class ReviewsProvider {
data: any;
constructor(public http: HttpClient) {
this.data = null;
}
getReviews(){
if (this.data) {
return Promise.resolve(this.data);
}
return new Promise(resolve => {
this.http.get('http://localhost:8080/api/reviews')
.map(res => res)
.subscribe(data => {
this.data = data;
resolve(this.data);
});
});
}
createReview(review){
let headers = new HttpHeaders();
headers.append('Content-Type', 'application/json');
this.http.post('http://localhost:8080/api/reviews', JSON.stringify(review), {headers: headers})
.subscribe(res =>
console.log(res));
}
deleteReview(id){
this.http.delete('http://localhost:8080/api/reviews/' + id).subscribe((res) =>
console.log(res));
}
}
Pages -> add-review.html
<ion-header>
<ion-toolbar transparent>
<ion-title>Add Review</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="close()"><ion-icon name="close"></ion-icon></button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list no-lines>
<ion-item>
<ion-label floating>Title</ion-label>
<ion-input [(ngModel)]="title" type="text"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Review</ion-label>
<ion-textarea [(ngModel)]="description"></ion-textarea>
</ion-item>
<ion-item>
<ion-range min="0" max="100" pin="true" [(ngModel)]="rating">
<ion-icon range-left name="sad"></ion-icon>
<ion-icon range-right name="happy"></ion-icon>
</ion-range>
</ion-item>
</ion-list>
<button ion-button full color="secondary" (click)="save()">Save</button>
</ion-content>
add-review.ts
import { Component } from '#angular/core';
import { ViewController } from 'ionic-angular';
/**
* Generated class for the AddReviewPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
#IonicPage()
#Component({
selector: 'page-add-review',
templateUrl: 'add-review.html',
})
export class AddReviewPage {
title: any;
description: any;
rating: any;
constructor(public viewCtrl: ViewController) {
}
save(): void {
let review = {
title: this.title,
description: this.description,
rating: this.rating
};
this.viewCtrl.dismiss(review);
}
close(): void {
this.viewCtrl.dismiss();
}
ionViewDidLoad() {
console.log('ionViewDidLoad AddReviewPage');
}
}
Home page -> home.html
<ion-header>
<ion-navbar transparent>
<ion-title>
Review King
</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="addReview()"><ion-icon name="add"></ion-icon></button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list no-lines>
<ion-item-sliding *ngFor="let review of reviews">
<ion-item>
<ion-avatar item-left>
<img src="https://api.adorable.io/avatars/75/{{review.title}}">
</ion-avatar>
<h2>{{review.title}}</h2>
<p>{{review.description}}</p>
<ion-icon *ngIf="review.rating < 50" danger name="sad"></ion-icon>
<ion-icon *ngIf="review.rating >= 50" secondary name="happy"></ion-icon>
{{review.rating}}
</ion-item>
<ion-item-options>
<button ion-button color="danger" (click)="deleteReview(review)">
<ion-icon name="trash"></ion-icon>
Delete
</button>
</ion-item-options>
</ion-item-sliding>
</ion-list>
</ion-content>
home.ts
import { Component } from '#angular/core';
import { NavController, ModalController } from 'ionic-angular';
import { AddReviewPage } from '../add-review/add-review';
import { ReviewsProvider } from '../../providers/reviews/reviews';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
reviews : any;
constructor(public navCtrl: NavController, public reviewService: ReviewsProvider, public modalCtrl: ModalController) {
}
ionViewDidLoad(){
this.reviewService.getReviews().then((data) => {
console.log(data);
this.reviews = data;
});
}
addReview(){
let modal = this.modalCtrl.create(AddReviewPage);
modal.onDidDismiss(review => {
if(review){
this.reviews.push(review);
this.reviewService.createReview(review);
}
});
modal.present();
}
deleteReview(review){
//Remove locally
let index = this.reviews.indexOf(review);
if(index > -1){
this.reviews.splice(index, 1);
}
//Remove from database
this.reviewService.deleteReview(review._id);
}
}
I was unable to figure out what I had been doing wrong. Can anyone please point it out? Is it a problem with my view pages, or the configuration in app.module.ts?
Please ensure that there is a rootPage set in your app.component.ts page.
If not, insert the following into the class
rootPage: any = HomePage;

ag-grid in jhipster angular 4

i'm trying to use ag-grid in a jhipster project. After adding ag-grid to my project, I imported the module in app.module:
{AgGridModule} from 'ag-grid-angular';
i modified the component in order to use ag-grid:
import { Component, OnInit, OnDestroy } from '#angular/core';
import { ActivatedRoute, Router } from '#angular/router';
import { Subscription } from 'rxjs/Rx';
import { JhiEventManager, JhiParseLinks, JhiAlertService } from 'ng-jhipster';
import { Typapp } from './typapp.model';
import { TypappService } from './typapp.service';
import { ITEMS_PER_PAGE, Principal, ResponseWrapper } from '../../shared';
import {ColDef, ColumnApi, GridApi} from 'ag-grid';
#Component({
selector: 'jhi-typapp',
templateUrl: './typapp.component.html'
})
export class TypappComponent implements OnInit, OnDestroy {
typapps: Typapp[];
typs: Typapp[]
currentAccount: any;
eventSubscriber: Subscription;
/**
* Declarations AG-GRID
*/
// rowdata and column definitions
rowData: Typapp[];
columnDefs: ColDef[];
// gridApi and columnApi
api: GridApi;
columnApi: ColumnApi;
constructor(
private typappService: TypappService,
private jhiAlertService: JhiAlertService,
private eventManager: JhiEventManager,
private principal: Principal
) {
this.columnDefs = this.createColumnDefs();
}
loadAll() {
this.typappService.query().subscribe(
(res: ResponseWrapper) => {
this.typapps = res.json;
},
(res: ResponseWrapper) => this.onError(res.json)
);
}
ngOnInit() {
this.loadAll();
this.principal.identity().then((account) => {
this.currentAccount = account;
});
this.registerChangeInTypapps();
/**
* modif component aggrid
*/
this.typappService.findAll().subscribe(
(rowData) => {
this.rowData = rowData
},
(error) => {
console.log(error);
}
)
}
ngOnDestroy() {
this.eventManager.destroy(this.eventSubscriber);
}
trackId(index: number, item: Typapp) {
return item.id;
}
registerChangeInTypapps() {
this.eventSubscriber = this.eventManager.subscribe('typappListModification', (response) => this.loadAll());
}
private onError(error) {
this.jhiAlertService.error(error.message, null, null);
}
/**
* AG GRID fonctions
*/
// one grid initialisation, grap the APIs and auto resize the columns to fit the available space
onGridReady(params): void {
this.api = params.api;
this.columnApi = params.columnApi;
this.api.sizeColumnsToFit();
}
// create some simple column definitions
private createColumnDefs() {
return [
{field: 'id'},
{field: 'libTyp'},
]
}
}
there is the code of component.html
<h6> without AGRID</h6>
<div *ngFor="let rd of rowData">
<span>{{rd.id}}</span>
<span>{{rd.libTyp}}</span>
</div>
<br/>
<h6> with AGRID</h6>
<ag-grid-angular style="width: 100%; height: 800px;"
class="ag-theme-fresh"
(gridReady)="onGridReady($event)"
[columnDefs]="columnDefs"
[rowData]="rowData">
</ag-grid-angular>
and this is the result:
What i'm doing wrong? why there is no results when i use ag-grid?
Even in the console there is no error.
Thank you very much.
I had the same issue. Did you import ag-theme-fresh.css to vendor.css? This did the trick for me.
\src\main\webapp\content\css\vendor.css:
...
#import '~ag-grid/dist/styles/ag-theme-fresh.css';

this.zone.run() - Ngzone error

I have a problem with sails + sails socket + angular4
import { Component, OnInit, NgZone } from '#angular/core';
import { routerTransition } from '../../router.animations';
import { Http } from '#angular/http';
import * as socketIOClient from 'socket.io-client';
import * as sailsIOClient from 'sails.io.js';
#Component({
selector: 'app-tables',
templateUrl: './tables.component.html',
styleUrls: ['./tables.component.scss'],
animations: [routerTransition()]
})
export class TablesComponent implements OnInit {
io:any;
smartTableData:any;
constructor(public http: Http, private zone: NgZone) {
this.io = sailsIOClient(socketIOClient);
this.io.sails.url = "http://localhost:1337";
this.io.socket.get('/posts', function(resData, jwr) {
console.log (resData);
return resData;
});
this.io.socket.on('updateposts', function(data) {
this.zone.run(() => {
this.smartTableData = data;
});
});
}
ngOnInit() {
}
}
When the socket broadcasts data, the line this.socket.on("updataposts") is run, but ngZone does not work.
zone.js:196 Uncaught TypeError: Cannot read property 'run' of undefined
I want to update data to view when receiving socket data. Please help me!
Thank you!

Resources