New to ionic2 want to know what is post method , where to use, where to write a code???
Here is the sample code
//ts code
constructor(public formBuilder: FormBuilder,
) {
this.signupForm = formBuilder.group({
firstName: ['', Validators.compose([Validators.maxLength(20), Validators.pattern('[a-zA-Z ]*'), Validators.required])]
});
//html code
<form [formGroup]="signupForm">
<ion-item>
<ion-label floating>FIRST NAME</ion-label>
<ion-input formControlName="firstName" type="text"></ion-input>
</ion-item>
</form>
-- want to post the signupForm!!
Well, let's keep it short for basic understanding of post method.
import { Http } from '#angular/http'; import { Observable } from 'rxjs';
then
doPost(someData: any): Observable<any> {
this.http.post('auth/login').map(response => {
return response.json();
});
}
then you call it with
doPost(myData).subscribe(response => console.log(response));
Related
I'm making a fullstack app with vue3, axios using FormKit. For editing existing records I want to populate the input fields with the current data fetched from a mysql database. I stripped down the code to everything needed to display my problem, which in this code example is populating the FormKit input field with the lotnumber I fetched via the asynchronous function "getLotById". The lotnumber appears in the paragraph section but not in the input field. How can I properly delay the rendering of the FormKit element until the lotnumber has been fetched? Here's my code:
<script>
// import axios
import axios from "axios";
export default {
name: "LotEdit",
data() {
return {
lotnumber: this.lotnumber
}
},
props: {
lotid: Number
},
created: async function () {
await this.getLotById();
},
methods: {
// Get Lot By Id
async getLotById() {
try {
const response = await axios.get(`http://localhost:5000/lot/${this.$route.params.id}`);
this.lotnumber = response.data.lotnumber;
console.log(response.data);
}
catch (err) {
console.log(err);
}
},
}
};
</script>
<template>
<div>
<FormKit
type="text"
name="lotnumber"
label="lotnumber"
placeholder=""
validation="required"
:value="lotnumber"
/>
</div>
<div>
<p> Here the lotnumber appears: {{ lotnumber }}</p>
</div>
</template>
I suggest using a v-model on the FormKit input. Because it is two-way bound it means as soon as the async/await completes the data is populated on the template too. Something like...
<FormKit
v-model="lotnumber"
type="text"
name="lotnumber"
label="lotnumber"
placeholder=""
validation="required"
:value="lotnumber"
/>
Getting a little smarter I managed to solve the problem in the following way:
<script>
// import axios
import axios from "axios";
export default {
name: "LotEdit",
data() {
return {
lotnumber: this.lotnumber
}
},
props: {
lotid: Number
},
mounted: async function () {
const response = await this.getLotById();
const node = this.$formkit.get('lotnumber')
node.input(response.data.lotnumber, false)
},
methods: {
// Get Lot By Id
async getLotById() {
try {
const response = await axios.get(`http://localhost:5000/lot/${this.$route.params.id}`);
console.log(response.data);
return response;
}
catch (err) {
console.log(err);
}
},
}
};
</script>
<template>
<div>
<FormKit
type="text"
id="lotnumber"
name="lotnumber"
label="lotnumber"
placeholder=""
validation="required"
:value="lotnumber"
/>{{ lotnumber }}
</div>
</template>
Feel free to post any recommendations as I'm not a pro yet...
I'm also still figuring out how to handle controlled forms but I guess an alternative way to do it is with Form Generation
<script>
export default {
// ...
async setup() {
try {
const response = await axios.get(`http://localhost:5000/lot/${this.$route.params.id}`);
const schema = [
{
$formkit: "text",
label: "Lot Number",
value: response.data.lotnumber,
validation: "required",
},
];
} catch (err) {
console.log(err);
}
return { schema }
}
// ...
}
</script>
<template>
<FormKit type="form">
<FormKitSchema :schema="schema" />
</FormKit>
</template>
UPDATE ON BOTTOM
I am trying to show data in an *ngFor that i'm getting from an object that is getting retrieved asynchronously from ionic storage. At the moment i am getting a blank screen.
I have tried multiple things like using async pipes in different manners.
Does anybody know the right way?
Here is my storage service method that is getting called:
public getFlow(flowId:number){
return this.storage.get(FLOWS_KEY).then((flows:Map<number,Flow>)=>{
return flows.get(flowId);
});
}
this returns a Promise<Flow>
this is my component code:
import { Component, OnInit } from '#angular/core';
import { ModalController } from 'ionic-angular';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Flow } from '../../model/Flow';
import { FlowService } from '../../model/services/flowService';
import {CreateTaskPage} from '../create-task/create-task'
import { Task } from '../../model/Task';
#IonicPage()
#Component({
selector: 'page-flow',
templateUrl: 'flow.html',
})
export class FlowPage {
flow;
constructor(public navCtrl: NavController, public navParams: NavParams,private flowService:FlowService,public modalCtrl: ModalController) {
this.flow = this.flowService.getFlow(Number(this.navParams.get("flowId")))
}
ngOnInit(): void {
}
ionViewDidLoad() {
console.log('ionViewDidLoad FlowPage');
}
createTask(){
const modal = this.modalCtrl.create(CreateTaskPage,{flowId:this.flow.flowId});
modal.present();
}
swipe(e,task:Task){
if(e.direction == 2){
console.log("panUp");
task.column--;
}
if(e.direction == 4){
console.log("panDown");
task.column++;
}
}
}
My html:
<ion-content padding>
<div *ngIf="(flow | async)">
<div *ngFor="let col of flow.columns;index as i">
<h2>{{col}}</h2>
<div *ngFor="let task of flow.getTasksFromCol(i)">
<ion-card (swipe)="swipe($event,task)">
<ion-item>
<h2>{{task}}</h2>
<button ion-button item-end clear icon-end>
<ion-icon name='more'></ion-icon>
</button>
<p>{{task}}</p>
</ion-item>
</ion-card>
</div>
</div>
</div>
<ion-fab right bottom>
<button ion-fab color="light"><ion-icon name="arrow-dropleft"></ion-icon></button>
<ion-fab-list side="left">
<button (click)="createTask()" ion-fab><ion-icon name="add-circle"></ion-icon></button>
<button ion-fab><ion-icon name="create"></ion-icon></button>
</ion-fab-list>
</ion-fab>
</ion-content>
Thanks for helping.
UPDATE:
I found one big mistake in my component it now looks like this:
flow:Flow;
constructor(public navCtrl: NavController, public navParams: NavParams,private flowService:FlowService,public modalCtrl: ModalController) {
this.flowService.getFlow(Number(this.navParams.get("flowId"))).then(flow =>{
this.flow = flow;
})
}
i also updated my html but it still isn't working: i now get error:
ERROR TypeError: _co.flow.getTasksFromCol is not a function
at Object.eval [as updateDirectives]
This is weird because this method exists in my Flow Model:
import { Task } from "./Task";
export class Flow {
//PK for 1-n relation with task
flowId:number;
projectName:string;
columns:string[];
tasks: Map<number,Task>;
constructor(flowId:number,projectName:string,columns:string[],tasks:Map<number,Task>){
this.flowId = flowId;
this.projectName = projectName;
this.columns = columns;
this.tasks = tasks;
}
public getTasks(){
return Array.from(this.tasks.values())
}
public getTasksFromCol(colNumber:number){
var tasks = new Array<Task>();
for(let task of Array.from(this.tasks.values())){
if(task.column == colNumber){
tasks.push(task)
}
}
return tasks;
}
}
UPDATE2
i now added this to my service
public getTasksFromCol(flowId:number,colNumber:number){
return this.storage.get(FLOWS_KEY).then((flows:Map<number,Flow>)=>{
var flow:Flow = flows.get(flowId);
var tasks = new Array<Task>();
for(let task of Array.from(flow.tasks.values())){
if(task.column == colNumber){
tasks.push(task)
}
}
return tasks;
});
}
do i just call this in my html page? i'm kinda stuck
I found your mistake.
You have created one variable.
flow:Flow;
You have assigned value to that variable.
this.flow = flow;
Now you need to understand that variable has contains some value related to what you have assigned. So you can't access flow.getTasksFromCol()
Thats the reason you have faced this error.
ERROR TypeError: _co.flow.getTasksFromCol is not a function at Object.eval [as updateDirectives]
Solution:-
Just move this getTasksFromCol() method to service and apply html like following,
I hope it's working. Let try this once and let me know if any error.
I'm using the following to fetch a single post from the WordPress REST API.
import React, { Component } from 'react';
import axios from 'axios';
class Post extends Component {
constructor() {
super();
this.state = {
post: [],
};
}
componentDidMount() {
axios.get('http://example.com/wp-json/wp/v2/posts?slug=some-post')
.then(response => {
this.setState({ post: response.data });
})
.catch(error => {
console.log(error);
});
}
render() {
return (
<div>
{this.state.post.map(single => {
return(
<div>
<h1>{single.title.rendered}</h1>
<p>{single.content.rendered}</p>
</div>
);
})}
</div>
);
}
}
export default Post;
Is there a better/more straightforward way to render the post without mapping an array?
If api returns array then you can take only first element, f.e.:
this.setState({ post: response.data[0] });
Of course you should use then some conditional rendering (map works with empty array):
if(!this.state.post) return <Loading />
I stored profile data in firebase and
trying to retrieve them and show them in template with slides.
(I am making a matching service.)
But it seems the template is loaded before data is assigned to variable.
When I am just retrieving one data, not list,
it works fine.
I tried all the solutions on the goole,
like using 'NgZone', *ngIf, etc but nothing worked.
Please help me.
My Error message.
FindMatePage.html:21 ERROR Error: Error trying to diff '[object Object]'. Only arrays and iterables are allowed
at DefaultIterableDiffer.diff (core.es5.js:7083)
at NgForOf.ngDoCheck (common.es5.js:1699)~~
My find-mate.ts file.
export class FindMatePage implements OnInit{
#ViewChild('profileSlide') slider: Slides;
profileList = [] as Profile[];
constructor(public navCtrl: NavController, public navParams: NavParams,
private databaseService: DataServiceProvider, private auth:
AuthServiceProvider,
) {}
ngOnInit(){
this.auth.getActiveUser().getIdToken()
.then((token: string) => (
this.databaseService.fetchProfileList(token)
.subscribe((list: Profile[]) => {
if(list) {
this.profileList = list;
console.log(this.profileList)
} else {
this.profileList = [];
}
})
))//then ends
}
My find-mate.html file
<ion-content class="tutorial-page">
<ion-slides *ngIf="profileList" #profileSlide pager
(ionSlideDidChange)="slideChanged()">
<ion-slide>
<h2 class="profile-title">Ready to Play?</h2>
<button ion-button large clear icon-end color="primary">
Continue
<ion-icon name="arrow-forward"></ion-icon>
</button>
</ion-slide>
<ion-slide *ngFor="let profile of profileList">
<ion-buttons block>
<button ion-button color="primary">채팅하기</button>
</ion-buttons>
<ion-item> {{profile.username}}</ion-item>
<ion-item> {{profile.gym}</ion-item>
<ion-item> {{profile.goal}}</ion-item>
<ion-item> {{profile.level}}</ion-item>
</ion-slide>
My part of data-service.ts file
//프로필 목록 가져오기
fetchProfileList(token: string) {
return this.http.get('https://fitmate-16730.firebaseio.com/profile-list.json?auth=' + token)
.map((response: Response) => {
return response.json();
})
.do((profileList: Profile[]) => {
if (profileList) {
console.log(profileList);
return this.profileList = profileList;
} else {
return this.profileList = null;
}
});
}
I am trying to generate a cookie auth from an ionic app as a front-end, and Wordpress as back-end (I'm using this JSON API USER plugin).
The first step is to generate the nonce : MYURLBASE/api/get_nonce/?controller=user&method=generate_auth_cookie
Then generate cookie: MYURLBASE/api/user/generate_auth_cookie/?nonce=375034fjwfn39u8&username=john&passsword=PASSWORD-HERE
I can get the nonce, but I'm having trouble building the service handling the request.
Here is my login.html:
<form [ngFormModel]="loginForm" (submit)="login(username, password)" style="padding-top: 50px">
<ion-list>
<ion-item>
<ion-label stacked-label>Nom d'utilisateur ou Email</ion-label>
<ion-input type="text" [(ngFormControl)]="username" value=""></ion-input>
</ion-item>
<ion-item>
<ion-label stacked-label>Mot de passe</ion-label>
<ion-input type="password" [(ngFormControl)]="password" value=""></ion-input>
</ion-item>
</ion-list>
<div>
<button block type="submit">Connexion</button>
</div>
</form>
This is my login.ts:
import {Page, NavController, Alert} from 'ionic-angular';
import { FORM_DIRECTIVES, FormBuilder, ControlGroup, Validators, AbstractControl, Control } from 'angular2/common';
import { Http, Headers, RequestOptions, Request, RequestMethod, Response } from 'angular2/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
import {LoginService} from './login.service';
import {WooPage} from '../woo/woo';
#Page({
templateUrl: 'build/pages/ecommerce/login/login.html',
providers:[LoginService],
})
export class LoginPage {
loginForm: ControlGroup;
username: AbstractControl;
password: AbstractControl;
response;
constructor(private loginService:LoginService, public nav: NavController,
fb: FormBuilder){
this.loginForm = fb.group({
username: ['', Validators.required],
password: ['', Validators.required]
});
this.username = this.loginForm.controls['username'],
this.password = this.loginForm.controls['password']
}
// For test purposes
getNonce() {
this.loginService.getNonce()
.subscribe(
response => this.response = response,
error => console.log(error));
}
// For test purposes
generateCookie() {
this.loginService.generateCookie(this.loginService.getNonce())
.subscribe(
response => this.response = response,
error => console.log(error));
}
login(
username:string,
password:string) :void {
this.loginService.login(
username = this.username.value,
password = this.password.value
)
.subscribe(
response => this.response = response,
error => console.log(error)
);
}
}
And finally my login.service.ts:
import {Injectable,Inject} from 'angular2/core';
import {Http,Headers,Response} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import {NavController, Alert} from 'ionic-angular';
#Injectable()
export class LoginService {
private nonceUrl = 'https://MYURL/api/get_nonce/?controller=user&method=generate_auth_cookie'
private cookieUrlBase = 'https://MYURL/api/user/generate_auth_cookie/?nonce='
constructor(private http:Http) {}
getNonce() {
let nonce = this.http.get(this.nonceUrl).map(res => res.json().nonce);
return nonce;
}
generateCookie(nonce) {
return this.http.get(this.cookieUrlBase+nonce+'&username='+'chuckNorris'+'&password='+'chuckchuck')
}
// TODO: login(
// username: string,
// password: string):Observable<any> {
//
// const body = JSON.stringify(username + password);
// let headers = new Headers();
//
// headers.append('Content-Type', 'application/x-www-form-urlencoded');
// return this.http.post(, body, {
// headers : headers
// }).map(res => res.json());
// }
}
When I call the generateCookie function, I get the following url generated:
https://MYURL/api/user/generate_auth_cookie/?nonce=[object%20Object]&username=chuckNorris&password=chuckchuck
How can I pass the nonce value, as not to be an object?
Is there a better way to achieve the login authentification?
Thanks for the help, as I'm pretty lost here...
Yin.
try with:
getNonce() {
return new Promise(resolve => {
this.http.get(this.nonceUrl)
.map(res => res.json())
.subscribe(data => {
console.log(data);
});
});
}
Then, the result is something like:
{"status":"ok","controller":"user","method":"generate_auth_cookie","nonce":"66e6054397"}
So, then pass only the "nonce" property and not the entire object: result.nonce
this.cookieUrlBase+result.nonce+'&username='+'chuckNorris'+'&password='+'chuckchuck'