Ionic - Passing Data to another page - angularjs

Hello i want to pass the user id (uid) from the home page to a user Details Page. Because i display multiple users on my home page i don’t wan to pass the user session id (as given by the JSON.parse(localStorage.getItem("userData")); ), i want to click on the name of any user on the home page and pass its id and other parameters on the user details page.
home.html
<p (click)="UserPage()" [innerHTML]="item.username | linky"></p>
home.ts
public userDetails: any;
public resposeData: any;
public dataSet: any;
public noRecords: boolean;
rootPage: any = HomePage;
pages: Array<{ title: string, component: any }>;
userPostData = {
uid: “”,
token: “”,
username: “”,
message: “”,
msg_id: “”,
title: “”,
description: “”,
media_pic: “”,
created:""
};
constructor(
public common: Common,
public navCtrl: NavController,
public app: App,
public menu: MenuController,
public authService: AuthService,
platform: Platform,
statusBar: StatusBar,
splashScreen: SplashScreen,
) {
const data = JSON.parse(localStorage.getItem("userData"));
this.userDetails = data.userData;
this.userPostData.uid = this.userDetails.uid;
this.userPostData.token = this.userDetails.token;
this.userPostData.username = this.userDetails.username;
this.userPostData.msg_id = this.userDetails.msg_id;
this.userPostData.message = this.userDetails.message;
this.userPostData.title = this.userDetails.title;
this.userPostData.description = this.userDetails.description;
this.userPostData.media_pic = this.userDetails.media_pic;
this.userPostData.created = this.userDetails.created;
this.noRecords = false
this.allArtists();
}
note: this is how i call the users via Auth Service
allArtists() {
this.common.presentLoading();
this.authService.postData(this.userPostData, “newsFeed”).then(
result => {
this.resposeData = result;
if (this.resposeData.friendsNewsFeed) {
this.common.closeLoading();
this.dataSet = this.resposeData.friendsNewsFeed;
console.log(this.dataSet);
} else {
console.log("No access");
}
},
err => {
//Connection failed message
}
);
}
UserPage() {
this.navCtrl.push(UserPage, { uid: this.userPostData.uid });
userProfile.ts
mport { NavController, App, AlertController, MenuController, NavParams } from “ionic-angular”;
export class UserPage {
public uid: string;
constructor(
public common: Common,
public navCtrl: NavController,
public app: App,
public menuCtrl: MenuController,
public navParams: NavParams,
public authService: AuthService
) {
this.uid = navParams.get(‘uid’);
console.log(this.uid);
this.userProfile();
}
}
auth-service.ts
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import 'rxjs/add/operator/map';
let apiUrl = "http://localhost/PHP-Slim-Restful1/api/";
//let apiUrl = 'https://api.thewallscript.com/restful/';
/*
Generated class for the AuthService provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class AuthService {
constructor(public http: Http) {
console.log('Hello AuthService Provider');
}
postData(credentials, type){
return new Promise((resolve, reject) =>{
let headers = new Headers();
this.http.post(apiUrl+type, JSON.stringify(credentials), {headers: headers}).
subscribe(res =>{
resolve(res.json());
}, (err) =>{
reject(err);
});
});
}
}

With NavParams, you doing it the right way already.
It is not visible for me how your item structure is. When you setup your links at your homepage like this: <p (click)="UserPage()" [innerHTML]="item.username | linky"></p>, you could pass the user id of this item into the function like this: UserPage(user.uid).
What happens now, is that your UserPage function already gets the right uid and can pass it to the detailed view.

OK I got the answer. You need to pass the parameters in the with onclick.
home.html
home.ts
UserPage(uid_fk) {
this.navCtrl.push(UserPage, { uid_fk: uid_fk });
console.log(uid_fk);
}

Related

Get the foreign key in a httpRequest in nestJs

I'm trying to make many request in nestJs and specially some with the role of my users and i wanted to be able to list all users who match user.role = "Role's name" but i can't get the foreign key user from my table role.
My controller look like this and both of my entities reference each other as a role can have one or many user and a user one and only one role.
import { Controller, Get, Param, Post } from '#nestjs/common';
import { Body } from '#nestjs/common/decorators';
import { AuthDto } from 'src/authentification/auth.dto';
import { Role } from './role.entity';
import { User } from './user.entity';
import { UserService } from './user.service';
#Controller('user')
export class UserController {
constructor(private readonly UserService: UserService){}
#Get()
async getAllUser(): Promise<User[]>{
return this.UserService.getListUser();
}
#Get('/Role')
async getListRole(): Promise<Role[]> {
return this.UserService.getListRole();
}
#Get('/Role/:role')
async getUserByRole(#Param('role') role : number): Promise<User[]> {
return this.UserService.getUserByRole(+role);
}
#Get('/Pseudo/:pseudo')
async getUserByPseudo(#Param('pseudo') pseudo : string): Promise<User> {
return this.UserService.getUserByPseudo(pseudo);
}
#Get('/id/:id')
async getUserById(#Param('id') id : number): Promise<User> {
return this.UserService.getUserById(+id);
}
#Post('/New')
async createUser(#Body() user: AuthDto){
return this.UserService.createUser(user);
}
}
and here is the service
import { Get, Injectable } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { AuthDto } from 'src/authentification/auth.dto';
import { Repository } from 'typeorm';
import { Role } from './role.entity';
import { User } from './user.entity';
#Injectable()
export class UserService {
constructor(
#InjectRepository(User) private usersRepository: Repository<User>,
#InjectRepository(Role) private rolesRepository: Repository<Role>
){}
getUserById(id): Promise<User> {
return this.usersRepository.findOneOrFail(id);
}
getUserByPseudo(pseudo: string): Promise<User> {
return this.usersRepository.findOne({pseudo});
}
getListRole(): Promise<Role[]> {
return this.rolesRepository.find();
}
getListUser(): Promise<User[]> {
return this.usersRepository.find();
}
getUserByRole(role): Promise<User[]> {
return this.usersRepository.find({where: {role: role}});
}
createUser(data: AuthDto){
const user = {
pseudo: data.username,
password: data.password,
pointEffort: 10,
scienceTab: [],
inventaire: [],
technologieTab: [],
role: {
id: 1,
nom: "joueur",
users: []
},
};
const result = this.usersRepository.save(user);
return result;
}
}
user.entity.ts
import { Place } from "src/place/place.entity";
import { Science } from "src/science/science.entity";
import { TechnologieUser } from "src/technologie/technologieUser.entity";
import { Column, Entity, ManyToMany, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { Role } from "./role.entity";
#Entity()
export class User {
#PrimaryGeneratedColumn()
id: Number;
#Column()
pseudo: String;
#Column()
password: String;
#Column()
pointEffort: Number;
#ManyToOne(type => Role, role => role.users)
role: Role;
#ManyToMany(type => Science, science => science.users)
scienceTab: Science[];
#OneToMany(type => TechnologieUser, technologieUser => technologieUser.user)
technologieTab: TechnologieUser[];
#OneToMany(type => Place, place => place.user)
inventaire: Place[];
}
role.entity.ts
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { User } from "./user.entity";
#Entity()
export class Role {
#PrimaryGeneratedColumn()
id: Number;
#Column()
nom: String;
#OneToMany(type => User, user => user.role)
users: User[];
}
But when i use getListRole() i only get this
And so i don't have the list of my users returned in the property role.users which is missing.
So the question is : how can i have role.users added in the data of getListRole()?
Thx a lot
Get role id from params, then do, this.usersRepository.find({ relations: {Role: true}, where: { role: { id: roleId } } })

IONIC 2 - Read OTP from sms and login to dashbord

I am working on auto-verification otp ionic2. In that, SMS permission is applied and if device mobile number exists or read otp from sms then it switch directly to dashboard page for that i use a function called watchSMS() as shown in angular code but it gives an error (SMS is not defined).
Any help will be highly appreciated.
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, AlertController, Platform, LoadingController, ToastController, ViewController } from 'ionic-angular';
import { FormGroup, FormBuilder, FormControl, Validators } from '#angular/forms';
import { Network } from '#ionic-native/network';
import { CrudHttpProvider } from '../../providers/crud-http/crud-http';
import { SQLite, SQLiteObject } from '#ionic-native/sqlite';
import { ConstantVariable } from '../../app/constant-variable';
import { HomePage } from '../home/home';
// import { SMS } from '#ionic-native/sms';
import { Sim } from "#ionic-native/sim";
import { AndroidPermissions } from '#ionic-native/android-permissions';
declare var window: any;
declare var SMS:any;
#IonicPage()
#Component({
selector: 'page-login',
templateUrl: 'login.html',
})
export class LoginPage {
public myForm: FormGroup;
public mobile: any;
public db_name: any;
public url_play_store: any;
public buttonDisabled: any;
public studname: any;
public tuition_name: any;
public prn: any;
public otp: any;
public api_key: any;
public userinfo:any;
public stored_mb:any;
public simInfo: any;
public cards: any;
public phoneNumber: any;
constructor(public navCtrl: NavController, public navParams: NavParams, public formBuilder: FormBuilder, public alertCtrl: AlertController, public platform: Platform, public network: Network, public loadingCtrl: LoadingController, public toastCtrl: ToastController, public crudHttpProvider: CrudHttpProvider, public sqlite: SQLite, public viewCtrl: ViewController, public sim: Sim, public androidPermissions: AndroidPermissions) {
this.db_name = ConstantVariable.db_name;
this.myForm = this.formBuilder.group({
'mobile': ['', [Validators.required]],
});
}
ionViewDidLoad() {
console.log('ionViewDidLoad LoginPage');
}
login() {
let post_data = { 'api_url': 'checkMobileNumber', "post": {'mobile': this.mobile} };
this.crudHttpProvider.callToCrudPost(post_data)
.then(data => {
let res = data;
if (res['status'] == 100) {
this.studname = res['data'].studname;
this.tuition_name = res['data'].tuition_name;
this.prn = res['data'].prn;
this.otp = res['data'].otp;
this.api_key = res['data'].api_key;
this.navCtrl.push('RegisterPage',{
"studname": this.studname,
"tuition_name": this.tuition_name,
"prn": this.prn,
"otp": this.otp,
"api_key": this.api_key
});
this.viewCtrl.dismiss();
this.checkPermission();
}
});
}
checkPermission() {
this.androidPermissions.checkPermission
(this.androidPermissions.PERMISSION.READ_SMS).then(
success => {
//if permission granted
this.watchSMS();
},
err =>{
this.androidPermissions.requestPermission
(this.androidPermissions.PERMISSION.READ_SMS).
then(success=>{
this.watchSMS();
},
err=>{
alert("cancelled")
});
});
this.androidPermissions.requestPermissions
([this.androidPermissions.PERMISSION.READ_SMS]);
}
watchSMS() {
if(window.SMS) window.SMS.startWatch(function(){
console.log('Succeed to start watching SMS');
this.navCtrl.push('DashboardPage');
let toast = this.toastCtrl.create({
message: "Succeed to start watching SMS.",
duration: 4000
});
toast.present();
document.addEventListener('onSMSArrive', this.smsArived);
}, function(){
console.log('failed to start watching SMS');
let toast = this.toastCtrl.create({
message: "failed to start watching SMS.",
duration: 4000
});
toast.present();
});
}
stopWatchSMS() {
if(window.SMS) window.SMS.stopWatch(function(){
console.log('Succeed to stop watching SMS');
}, function(){
console.log('failed to stop watching SMS');
});
}
smsArived = (result: any) => {
console.log("SMS DATA 2" + result);
let toast = this.toastCtrl.create({
message: "RESULT " + result,
duration: 4000
});
toast.present();
this.stopWatchSMS();
}
}
I implemented auto verify OTP via this tutorial. I had no trouble.
SMS is called inside of platform.ready() and it says : "Make sure always use method in Ionic Framework inside the platform.ready() else it will not work.". Finally, I think, you dont need to use window.
ionViewDidEnter()
{
this.platform.ready().then((readySource) => {
if(SMS) SMS.startWatch(()=>{
console.log('watching started');
}, Error=>{
console.log('failed to start watching');
});
document.addEventListener('onSMSArrive', (e:any)=>{
var sms = e.data;
console.log(sms);
});
});
}

Create callback in Ionic 2 for Observable.timer

I have a Observable.timer function that creates a countdown and I want to call a specific function called endTimer() when the timer has ended inside my #Component without using setTimeout(). I can check the value of counter == 0 in the view but how do I check in the #Component
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, ModalController } from 'ionic-angular';
import { Storage } from '#ionic/storage';
import { Observable } from 'rxjs/Observable'
import 'rxjs/add/observable/timer'
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/take'
//imported pipes
import {FormatTimer} from '../../pipes/formattimer';
#Component({
selector: 'page-livegame',
templateUrl: 'livegame.html',
pipes: [FormatTimer]
})
export class LivegamePage {
gamesData: any;
countDown: any;
counter = 1*60;
tick = 1000;
constructor(public modalCtrl: ModalController, public navCtrl: NavController, public navParams: NavParams, public storage: Storage) {
//setTimeout(function(){ endTimer(); }, 300000);
}
ionViewDidLoad() {
this.getCurrentGame();
}
ngOnInit() {
this.countDown = Observable.timer(0, this.tick)
.take(this.counter)
.map(() => --this.counter);
}
endTimer() {
console.log('ended');
}
}
<div *ngIf="counter == 0">the timer has ended </div>
Are you subscribing to it somewhere? on the template with 'async' pipe or so? If not, you have to subscribe to it. For the same reason, the variable 'this.counter' will never reach 0.
If you are already subscribing to it on the template with async Pipe, you can use the operator finally:
ngOnInit() {
this.countDown = Observable.timer(0, this.tick)
.take(this.counter)
.map(() => --this.counter)
.finally(() => this.endTimer())
}
if you are not subscribing to it on the template, you can subscribe like this:
ngOnInit() {
this.countDown = Observable.timer(0, this.tick)
.take(this.counter)
.map(() => --this.counter)
.finally(() => this.endTimer())
.share() // Avoid multiple side effect if multiple subscribers
this.countDown.subscribe(() => { /* do nothing */})
}
Hope this helps.

Simple attempt to get json data into an array

I have the data being printed out to a log . Have do I simply put this in an array? So I can do
<ul *ngIf="courses$ | async as courses else noData">
<li *ngFor="let course of courses">
{{course.name}}
</li>
</ul>
<ng-template #noData>No Data Available</ng-template>
export class SurveyComponent {
surveys: Survey[];
survey: Survey;
constructor(private http: HttpClient) {
}
ngOnInit(): void {
this.http.get('http://localhost:54653/api/survey/').subscribe(data => {
console.log(data);
},
err => {
console.log('Error occured.');
}
);
}
}
export class Survey {
constructor(id?: string, name?: string, description?: string) {
this.id = id;
this.name = name;
this.description = description;
}
public id: string;
public name: string;
public description: string;
}
EDIT 1: Why does the first .map work and the other doesn't ?
Like this ?
surveys$: Observable<Survey[]>;
ngOnInit(): void {
this.surveys$ = this.http.get<Survey[]>('http://localhost:54653/api/survey/');
}
You can use rxjs map operator after your API call:
...
courses$: Observable<Survey[]>
...
ngOnInit(): void {
// if you want use the async pipe in the view, assign the observable
// to your property and remove .subscribe
this.courses$ = this.http
.get('http://localhost:54653/api/survey/')
.map(surveys =>
surveys.map(survey => new Survey(survey.id, survey.name, survey.description))
)
}
...

Representing Mongoose model as a Typescript class

I'm writing a simple web application using Angular 2 written in TypeScript. MongoDB is my database on a Mongoose framework while running on a Node server on an Express framework. My MongoDB and Node code is written in vanilla JS.
Now, I created a Mongoose model for a Country as following:
"use strict";
const Schema = require('mongoose').Schema,
db = require('../../config/database');
let countrySchema = new Schema({
countryName: { type: String, index : { unique : true } }
});
let Country = db.model('Country', countrySchema);
module.exports = Country;
Now, Country is what I want my object to be. In my app component, I have:
import { Component } from '#angular/core';
import { CountryService } from '../services/country.service';
import { Country } from '../models/country.model';
#Component({
selector: 'my-app',
templateUrl: 'app/views/app.component.html',
providers: [ CountryService ]
})
export class AppComponent {
originCountries: Country[];
destinationCountries: Country[];
constructor(private countryService: CountryService) { };
ngOnInit() {
this.getCountries();
}
getCountries() {
this.countryService.getCountries()
.then(countries => {
this.originCountries = countries;
this.destinationCountries = countries;
});
}
}
See how originCountries and destinationCountries should be arrays of Countries? I can't just import Country from the Country model (even though it sounded right in my head at the time).
What is the best way to create a country class that is based on the Mongoose model?
You use an interface like this ICountry:
export interface ICountry {
_id: string;
name: string;
}
You can now use this interface in your mongoose setup:
import mongoose = require('mongoose');
import { ICountry } from './interfaces';
var _schema: mongoose.Schema = new mongoose.Schema({
name: { type: String, required: true, index: { unique: true } }
});
type CountryType = ICountry & mongoose.Document;
var _model = mongoose.model <CountryType> ('Country', _schema);
export class Country {
static getAll(): Promise<Array<ICountry>> {
return new Promise<ICountry> ((resolve, reject) => {
_model.find((err, counties) => {
err ? reject(err) : resolve(counties);
});
});
}
}
And the route setup:
var router = express.Router();
router.get('/api/countries', (req, res) => {
Country.getAll().then(c => {
return res.json(c);
});
});
And implement it in your Angular application, if you need some methods or just import the interface direct in your service class:
import { ICountry } from '../../interfaces';
...
countries: Array<ICountry>
This is how I do it in my project:
In my schema file:
///<reference path="../typings/mongoose/mongoose.d.ts"/>
import * as mongoose from 'mongoose';
var UserSchema = new mongoose.Schema({
name: String,
// ...
});
export interface IUser extends mongoose.Document {
_id: string;
name: string;
// ...
}
export interface IUserModel extends mongoose.Model<IUser> { }
export var User: IUserModel = <IUserModel>mongoose.model<IUser>('User', UserSchema);
In the server side code:
import {User, IUser, IUserModel} from '../schemas/user.schema';
// ...
User.findOne({ ... });
In the client side code I now can use the IUser interface:
import {IUser} from '../---/schemas/user.schema';
// ...
userCache: Array<IUser>;

Resources