airtable 使用link
AirTable Link
2020/11/18
** 感謝張晴惠同學提供本範例 **
以下的範例使用到兩個table: users及positions,users裡有Name、Position、Age。其中Position是Link,連接到positions。因為是一對多的連結,所以,是以陣列儲存,跟relational database不一樣的是,連結儲存的是record id(不是數值或字串)。所以,使用Link必須儲存record id。
import React, { useEffect , useState } from 'react'
import {
View,
Text,
StyleSheet,
Alert,
Button,
KeyboardAvoidingView,
ScrollView
} from 'react-native'
import {
Item,
Input,
Icon,
Picker,
} from 'native-base'
import axios from 'axios'
const axios_config = {
headers: {
'Authorization': 'Bearer keynrPAqoJh2OKPgk',
"Content-Type": "application/json"
}
}
function ApplyForm () {
// 存放airtable裡面users的data
const [users, setUsers] = useState(null)
// 存放airtable裡面職位的data
const [positionType, setPostionType] = useState(null)
const [name, setName] = useState('')
const [age, setAge] = useState('')
// 存放id的原因是Airtable table users裡面position的欄位是以id去存放資料
const [positionId, setPostionId] = useState('')
// submit function
async function handleSubmit() {
try {
const body ={
fields: {
Name: name,
Position: [positionId], // api doc 規定是以array存放
Age: age,
}
}
const result = await axios.post('https://api.airtable.com/v0/apptoQzVgry24n6Ad/users',
body,
axios_config
)
// 如果成功,清除表單資料和重新get users的資訊
if(result .status === 200) {
Alert.alert('Success')
setPostionId('')
setName('')
setAge('')
getUsers()
} else {
Alert.alert('Error')
}
} catch(err){
console.log('err', err)
}
}
// get users (api)
// 為了看有沒有成功新增
async function getUsers() {
try {
const result = await axios.get("https://api.airtable.com/v0/apptoQzVgry24n6Ad/users?view=Grid%20view", axios_config)
setUsers(result.data.records)
} catch(err){
console.log('err', err)
}
}
// get positions (api) -> 因為有users table Position這個欄位是link到positions table的
// 所以Position(from users)欄位存放的是positions table的id
// 新增user的時候就必須帶上position的id
// 我們用select的方式 限制使用者送出的資料(只能是position table的id)
// 所以我們必須先找到這些id (get positions table)
async function getPositions() {
try {
const result = await axios.get('https://api.airtable.com/v0/apptoQzVgry24n6Ad/positions?view=Grid%20view', axios_config)
setPostionType(result.data.records)
} catch(err){
console.log('err', err)
}
}
// 一進去先get
useEffect(()=> {
getPositions()
getUsers()
}, [])
// 我們users裡面只有存id,要透過這個id再去position找Name(因為顯示出來的是Name)
function findThePostion (user) {
const find = positionType.find((position)=>position.id === user.fields.Position[0])
return find.fields.Name
}
return (
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={Platform.OS == "ios" ? "padding" : "height"}
>
<ScrollView style={styles.container}>
{positionType && users && users.map((user, index)=>{
return (
<View style={styles.userItem} key={`user-${index}`}>
<Text>姓名 : {user.fields.Name}</Text>
<Text>年齡 : {user.fields.Age}</Text>
<Text>職位 : {findThePostion(user)}</Text>
</View>
)
})}
<View style={styles.inputItem}>
<Text style={styles.label}>姓名</Text>
<Item regular>
<Input
placeholder="請輸入姓名"
value={name}
onChangeText={(val)=>setName(val)}/>
</Item>
</View>
<View style={styles.inputItem}>
<Text style={styles.label}>年齡</Text>
<Item regular>
<Input
placeholder="請輸入年齡"
value={age}
onChangeText={(val)=>setAge(val)}
keyboardType="number-pad"
/>
</Item>
</View>
<View style={styles.inputItem}>
<Text style={styles.label}>職位</Text>
<Picker
mode="dropdown"
iosIcon={<Icon name="arrow-down" />}
placeholder="選擇職位"
placeholderStyle={{ color: "#bfc6ea" }}
placeholderIconColor="#007aff"
selectedValue={positionId}
onValueChange={(v)=>setPostionId(v)}
>
{ // 選項需限定從postionType map 出來
positionType && positionType.map((position)=> {
return (
<Picker.Item
label={position.fields.Name}
key={position.id}
value={position.id} />
)
})}
</Picker>
</View>
<Button
onPress={handleSubmit}
title="送出"
/>
</ScrollView>
</KeyboardAvoidingView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
marginTop: 48
},
text:{
fontSize: 56,
fontWeight: 'bold',
color: '#374c72'
},
headerTitle: {
color:'#fff',
fontSize: 28
},
inputItem: {
marginBottom: 16
},
label: {
fontSize: 16,
marginBottom: 4
},
userItem: {
marginBottom: 8,
padding: 6,
borderBottomColor: '#ccc',
borderBottomWidth: 1
}
});
export default ApplyForm