I have created a sub component for updating values of recipes I fetch from API. However when I do so I get:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `UpdateCourse`.
Navigator to the Update function component:
<Button
title="UPDATE RECIPE"
style={Styles.searchBtn}
onPress={() =>
navigation.navigate("Update_course", {
id: "60c9a32cb076563888b5782a",
})
}
/>
</View>
Update Component:
import React, { useState, useEffect } from "react";
import { Button, Image, TextInput, Text, Linking, View } from "react-native";
import Styles from "../../styles/Styles";
import Alert from "../elements/Alert";
import Axios from "axios";
import APIRequest from "../elements/APIRequest";
export default function UpdateCourse(id) {
const [dishName, setdishName] = useState("");
const [category, setcategory] = useState("");
const [author, setauthor] = useState("");
const [ingredients, setingredients] = useState([]);
const [cookingTime, setcookingTime] = useState("");
const [sourceUrl, setsourceUrl] = useState("");
const [imageUrl, setimageUrl] = useState("");
const [isPublished, setisPublished] = useState("true");
const [price, setprice] = useState("");
const [tags, settags] = useState([]);
const [alert, setAlert] = useState("");
const url = `http://x.x.x.x:1234/api/courses/find/${id}`;
useEffect(() => {
async function getData() {
const result = await Axios.get(url);
setdishName(result.data.dishName);
setcategory(result.data.category);
setauthor(result.data.author);
setingredients(result.data.ingredients);
setcookingTime(result.data.cookingTime);
setsourceUrl(result.data.sourceUrl);
setimageUrl(result.data.imageUrl);
setisPublished(result.data.isPublished);
setprice(result.data.price);
settags(result.data.tags);
}
getData();
}, [url]);
async function update() {
let item = {
dishName,
category,
author,
ingredients,
cookingTime,
sourceUrl,
imageUrl,
isPublished,
price,
tags,
};
const result = await APIRequest(
`http://x.x.x.x:1234/api/courses/${id}`,
"PUT",
JSON.stringify(item)
);
if (result.status !== 200) {
return setAlert(
result.status +
" " +
result.statusText +
" - Please check TextInput fields"
);
}
}
const handleIngredientsChange = (event, index) => {
const shallowCopy = [...ingredients];
shallowCopy[index] = {
...shallowCopy[index],
[event.target.id]: event,
};
setingredients(shallowCopy);
};
return (
<View style={{ minWidth: 70 }}>
<View style={(Styles.bigBar, { textAlign: "center" })}>
<Text> Update recipe</Text>
</View>
<View
style={{
backgroundColor: "#f1f1f1",
padding: 3,
borderRadius: 1,
marginBottom: 7,
}}
>
<View style={{}}>
{alert !== "" && (
<View style={{ display: "flex", justifyContent: "center" }}>
<Alert alert={alert}></Alert>
</View>
)}
<View>
<Text>Name of the course</Text>
<TextInput
style={Styles.formControl}
value={dishName}
onChangeText={e => setdishName(e)}
/>
</View>
<View>
<Text>Category</Text>
<TextInput
style={Styles.formControl}
value={category}
onChangeText={e => setcategory(e)}
/>
</View>
<View>
<Text>Author</Text>
<TextInput
onChangeText={e => setauthor(e)}
style={Styles.formControl}
value={author}
/>
</View>
<View style={{ marginBottom: 2 }}>
<Text>Ingredients</Text>
</View>
{ingredients.map(({ quantity, unit, description }, index) => {
return (
<View style="ing" key={"key" + index}>
<Text>Quantity </Text>
<TextInput
key={"quantity" + index}
style={
(Styles.formControl,
{
marginLeft: 1,
marginRight: 1,
width: 5,
})
}
onChangeText={event => handleIngredientsChange(event, index)}
value={quantity}
/>
<View style={{ marginRight: 2 }}> Unit </View>
<View>
<TextInput
key={"unit" + index}
style={(Styles.formControl, { width: 5 })}
onChangeText={event =>
handleIngredientsChange(event, index)
}
value={unit}
/>
</View>
<View style={{ marginLeft: 1 }}>
{" "}
<Text>Description</Text>{" "}
</View>
<TextInput
key={"description" + index}
style={(Styles.formControl, { marginLeft: 1 })}
onChangeText={event => handleIngredientsChange(event, index)}
value={description}
/>
</View>
);
})}
<View>
<Text>Cooking time</Text>
<TextInput
onChangeText={e => setcookingTime(e)}
style={Styles.formControl}
value={cookingTime}
/>
</View>
<View>
<Text>Source url</Text>
<TextInput
onChangeText={e => setsourceUrl(e)}
style={Styles.formControl}
value={sourceUrl}
/>
</View>
<View>
<Text>Image url</Text>
<TextInput
onChangeText={e => setimageUrl(e)}
style={Styles.formControl}
value={imageUrl}
/>
</View>
<View>
<Text>Publish state</Text>
<TextInput
onChangeText={e => setisPublished(e)}
style={Styles.formControl}
placeholder={"default: true"}
/>
</View>
<View>
<Text>Price</Text>
<TextInput
onChangeText={e => setprice(e)}
style={Styles.formControl}
value={price}
/>
</View>
<View>
<Text>Tags</Text>
<TextInput
onChangeText={e => settags(e)}
style={Styles.formControl}
value={tags}
/>
</View>
<View style={(Styles.prettyB, { textAlign: "center" })}>
<Button onPress={update} title="Submit"></Button>
</View>
</View>
</View>
</View>
);
}
Sample data:
{"isPublished":true,"tags":["pizza","greek"],"_id":"60c9e360b076563888b578a2","dishName":"Greek pizza","category":"pizza","author":"Paolo","ingredients":[{"_id":"60c9e360b076563888b578a3","quantity":0.75,"unit":"cup","description":"warm water"},{"_id":"60c9e360b076563888b578a4","quantity":0.5,"unit":"cup","description":"bread flour"},{"_id":"60c9e360b076563888b578a5","quantity":1.5,"unit":"tea spoon","description":"sea salt"},{"_id":"60c9e360b076563888b578a6","quantity":1,"unit":"cup","description":"baby arugula"},{"_id":"60c9e360b076563888b578a7","quantity":0.67,"unit":"cup","description":"grape tomatoes halved"},{"_id":"60c9e360b076563888b578a8","quantity":1,"unit":"drizzle","description":"olive oil"},{"_id":"60c9e360b076563888b578a9","quantity":1.5,"unit":"tea spoon","description":"dry active yeast"},{"_id":"60c9e360b076563888b578aa","quantity":2,"unit":"tea spoon","description":"sugar"},{"_id":"60c9e360b076563888b578ab","quantity":1,"unit":"lb","description":"hummus any variety"},{"_id":"60c9e360b076563888b578ac","quantity":0.67,"unit":"cup","description":"good pitted greek olives"},{"_id":"60c9e360b076563888b578ad","quantity":0.25,"unit":"cup","description":"crumbled feta cheese"}],"cookingTime":75,"sourceUrl":"https://www.crete.pl/kuchnia-grecka-dania-glowne-wegetarianskie/grecka-pizza-z-feta.html","imageUrl":"https://www.crete.pl/zdjecia/grecka-pizza-z-feta/pizza1.jpg","price":35.99,"date":"2021-06-16T11:41:20.508Z","__v":0}
However it does work fine when I use . It then displays text I created. I do not understand why I cannot put Input tags on this subpage however. Thank you for all help!