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