Cannot pass the fetch method information to the instance data - vue.js

When I run the below code, the values inside the currencie variable are not displayed.
I cannot pass the fetch method information to the instance data. I would like to fetch the data and display it on the screen. If I use console.log I can see the data as expected.
<template>
<Page class="page">
<ActionBar title="Tela N°1" class="action-bar" />
<ScrollView>
<StackLayout class="home-panel">
<!--Add your page content here-->
<Label textWrap="true" text="Primeira tela criada usando NativeScript"
class="h2 description-label" />
<Button text="Segunda Tela" #tap="onButtonTap" />
<Button text="Terceira Tela" #tap="onButton" />
<ListView class="list-group" for="currencie in currenciess"
style="height:1250px">
<v-template>
<FlexboxLayout flexDirection="row" class="list-group-item">
<Label :text="currencie.name" class="list-group-item-heading" style="width: 60%" />
<Label :text="currencie.buy" class="list-group-item-heading"
style="width: 60%" />
</FlexboxLayout>
</v-template>
</ListView>
</StackLayout>
</ScrollView>
</Page>
</template>
<script>
import Second from "./Second";
import Third from "./Third";
const http = require("tns-core-modules/http");
const url = "https://api.hgbrasil.com/finance?key=c5239f9c";
export default {
data() {
return {
currenciess: []
};
},
mounted() {
fetch(url)
.then(response => response.json())
.then(results => {
this.currenciess = results.results.currencies.USD;
});
},
};
</script>

Change your mounted method. currenciess is an array while your results.results.currencies["USD"] is an object coming from API. I have created a playground for you here.
mounted() {
console.log("mounted");
fetch(url)
.then(response => response.json())
.then(results => {
this.currenciess.push(results.results.currencies["USD"]);
});
}

Related

why getting error while uploading image in react

I created a form with name, order, image, status feild in my application. I used material design for form design and used react-material-file-upload for image upload.i got the values and viewed in console.After submitting the form it is not added in my web api,getting error in file.filename not defined in server.
Add.js
import FileUpload from "react-material-file-upload";
import TextField from '#mui/material/TextField';
import Grid from '#mui/material/Grid';
function Addcategory(props){
const [files, setFiles] = useState([]);
const handleSubmit =async (event) =>{
event.preventDefault();
const userid=localStorage.getItem("id");
const fileimg =files[0];
console.log(fileimg);
const userData = {
catname:event.target[0].value,
catorder:event.target[2].value,
image:fileimg,
enable:event.target[4].value,
status:1,
createdBy:userid
}
console.log(userData);
await CategoryDataService.create(userData)
.then(res => {
const data=res.data;
console.log(res);
toast.success("Category Added Successfully");
})
.catch((err) => {
// console.log("err",err.response);
toast.error("please try again!");
});
}
return(
<ThemeProvider theme={theme}>
<div style={{ margin:" 30px 130px 30px"}}>
<Box sx={{ border: '2px solid #15171c', borderRadius: '10px'}} >
<Grid container rowSpacing={1} columnSpacing={{ xs: 1, sm: 2, md: 3 }}>
<Grid item xs={12} style={{textAlign:"center"}}>
<h2 style={{textAlign:"center"}}>Category Add</h2>
<Box
component="form"
sx={{
'& .MuiTextField-root': { m: 1,},
}}
onSubmit={handleSubmit}
noValidate
autoComplete="off"
>
<div className="form-display">
<Grid >
<TextField
required
id="outlined-text"
label="Category Name"
name="catname"
autoFocus/>
<TextField
id="outlined-text"
label="Category Order"
name="catorder"
type="number"
/>
<TextField
id="outlined-select-currency"
select
label="Category Status"
name="enable"
helperText="Please select actegory status"
>
{catStatus.map((option) => (
<MenuItem key={option.value} value={option.value} >
{option.label}
</MenuItem>
))}
</TextField>
<Grid item xs={12} columnSpacing={{xs:1}}>
<Grid item xs={12}>
<FileUpload value={files} onChange={setFiles} />
</Grid>
</Grid>
<Stack direction="row" spacing={2} justifyContent="center"
style={{margin:"15px"}}>
<Button variant="outlined" type="submit">
Submit {props.children}
</Button >
<Button variant="outlined" onClick={back}>
Cancel
</Button>
</Stack>
</Grid>
</div>
</Box>
</Grid>
</Grid>
</Box>
</div>
</ThemeProvider>
);
}
server.js
const multer=require("multer");
const fileStorageEngine = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "./uploads");
},
filename:(req, file, cb) =>{
cb(null, Date.now() + "-" + file.originalname);
}
});
const upload = multer({ storage: fileStorageEngine });
app.post('/addCategory', upload.single("image"), async(req,res)=>{
// let file = req.file;
const data={
category_order:req.body.catorder,
category_name:req.body.catname,
category_icon:req.file.filename,
category_enable_disable:req.body.enable,
status:req.body.status,
created_by:req.body.createdBy,
createdAt:Date.now()
}
await models.category.create(data).then(result=>{
res.status(201).json({
Code: "1",
Message: "Category created successfully",
Data: result
});
})
.catch(error=>{
res.status(500).json({
Code: "0",
Message: "Something went wrong,try again.",
Post: error
});
})
});
this api is working in postman but not working while submit the form

Having problems calling an API id

Hi I am having some problems figuring out how to access an id. I am making a twitter cloner and I have an Icon I would like to click and see what people are commenting on it. But I have hit a wall and cant figure out how to access the Id when the chatbubble is clicked.
Any help would be greatly appreciated. The API works perfectly and I can call an id through postman.
const GetData = (id) => {
axios.get('https://localhost:44368/api/users/{id}').then((response) => {
console.log(response.data, "list of heroes ");
});
};
return (
<div className="post">
<div className="ppictur">
<Avatar src={avatar} />
</div>
<div className="post_body">
<div className="post_header">
<div className="post_headerText">
<h3>
{displayName}
<span className="post_headerSpecial">
<VerifiedIcon className="post_badge" />
#{username}
</span>
</h3>
</div>
<div className="post_headerDesription">
<p>{text}</p>
</div>
</div>
<img src={image} alt="" />
<div className="post_footer">
<ChatBubbleOutlineIcon onClick={GetData()} />
<RepeatIcon fontSize="small" />
<FavoriteBorderIcon fontSize="small" />
<PublishOutlinedIcon fontSize="small" />
</div>
</div>
</div>
);
}
export default Post;
const [posts, setPosts] = useState([]);
useEffect(() => {
axios.get('https://localhost:44368/api/users').then((response) => {
console.log(response.data, "list of heroes ");
setPosts(response.data);
});
}, []);
const icon = document.getElementById("Dark");
function DarkM() {
document.body.classList.toggle("dark-theme");
}
return (
<div className="commentbox">
<div className="header">
<h2>Home</h2>
<DarkModeOutlinedIcon id="Dark" onClick={() => DarkM(icon)} />
</div>
<Opinion />
{posts.map(post => (
<Post
avatar={post.profilePicture}
displayName={post.name}
username={post.userName}
text={post.post}
image={post.image}
bull
/>
)).reverse()}
</div>
);
}
export default Feed; ```
Use template literal ES6 with backticks.
const GetData = (id) => {
axios.get(`https://localhost:44368/api/users/${id}`).then((response) => {
console.log(response.data, "list of heroes ");
});
};
Also when you call it, make sure to pass arguments.
<ChatBubbleOutlineIcon onClick={GetData(9)} />
In my other component i wasnt pushing all the data through. that is my props didnt know what i was trying to call
const objectToPass = {
postId, avatar, displayName, username, text, image
}
const showSingleData = (value) => {
navigate(`/tweet/${value.postId}`)
console.log(value)
}```
it was a problem with my other component

How to combine two values from child components with an event?

I can't assign data from child component.
I am simply trying to implement emitting a specific value with an event
Child component is:
<template>
<StackLayout orientation="vertical" width="210" height="210"
backgroundColor="blue" color="white">
<Label text="Father" row="0" col="1"
class="h2 text-center p-t-5 text-primary" />
<ListPicker :items="maleName" v-model="maleIndex" row="1" col="1"
#selectedIndexChange="selectedIndexofFatherChanged" />
</StackLayout>
</template>
<script>
export default {
data() {
return {
maleName: [
"Rey",
"Antonia",
"Victor",
"Lincoln",
],
maleIndex: 0
};
},
methods: {
selectedIndexofFatherChanged() {
this.$emit("fatherChanged", this.fatherName);
// console.log("changed to: " + this.fatherName);
}
},
computed: {
fatherName() {
return this.maleName[this.maleIndex];
}
}
};
</script>
and Parent Component is:
<template>
<Page>
<ActionBar title="Choose Parent" />
<GridLayout columns="*, *" rows="*,90">
<SelectMother col="0" #motherChanged="onMotherChanged">
</SelectMother>
<SelectFather col="1" #fatherChanged="onFatherChanged">
</SelectFather>
<Button text="Show Result" #tap="onButtonTap" row="2"
colSpan="2" />
</GridLayout>
</Page>
</template>
<script>
import SelectMother from "./SelectMother";
import SelectFather from "./SelectFather";
export default {
components: {
SelectMother,
SelectFather
},
data() {
return {
motherName: null,
fatherName: null
};
},
methods: {
onButtonTap() {
alert("father: " + this.fatherName + " mother: " + this
.motherName);
},
},
watch: {
onFatherChanged(nameFromComponent) {
nameFromComponent = this.fatherName;
},
onMotherChanged(nameFromComponent) {
nameFromComponent
= this.motherName;
}
},
};
</script>
When I console log payload in onFatherChanged method it turns null
How to combine father and mother and show results.
Select Father from child component
Select Mother from second child component
Assign incoming payload and Show Results
Please check {N} Playground
https://play.nativescript.org/?template=play-vue&id=Dez2fV&v=26
Instead of
onFatherChanged(payload) {
payload = this.fatherName;
console.log(payload);
},
It should be;
onFatherChanged(payload) {
this.fatherName = payload;
console.log(payload);
},

How to handle navigation on a Nativescript Vue app?

I'm having issue understanding how navigation works using NativeScript Vue. I started yesterday and can't seem to make it work. It says my AppDrawer component is recursive.
The main frame contain a page, which contain the menu and the action bar. If I click on something, it loads the new page in the main frame and reload the menu and the action bar. Or does people just use a frame in the middle to load the pages without having to redraw the menu/drawer? Doing so, how would I change the data in the actionbar or the drawer from inside the frame? I'm guessing using Vuex, but I'm not quite sure what is the optimal approach when designing an android app.
Sorry if I get some terminology wrong.
nav/AppDrawer.vue:
<template>
<StackLayout ~drawerContent backgroundColor="#444">
<Label class="drawer-header" text="Drawer" />
<Label class="drawer-item" text="Accueil" #tap="btnHome()" />
<Label class="drawer-item" text="Item 2" #tap="btnAdd2()" />
<Label class="drawer-item" text="Item 3" #tap="btnHistory()" />
</StackLayout>
</template>
<script>
// Load pages
import App from "../App";
import Add2 from "../Add2";
import History from "../History";
export default {
components: {},
methods: {
btnHome() {
this.$navigateTo(App);
},
btnAdd2() {
this.$navigateTo(Add2);
},
btnHistory() {
this.$navigateTo(History);
},
},
};
</script>
App.vue:
<template>
<Page>
<ActionBar>
<GridLayout width="100%" columns="auto, *">
<Label
text="MENU"
#tap="$refs.drawer.nativeView.showDrawer()"
col="0"
/>
<Label class="title" text="Title" col="1" />
</GridLayout>
</ActionBar>
<RadSideDrawer ref="drawer">
<AppDrawer />
<GridLayout ~mainContent columns="*" rows="*">
<TextView editable="false">
<FormattedString>
<Span :text="msg" />
</FormattedString>
</TextView>
</GridLayout>
</RadSideDrawer>
</Page>
</template>
<script>
import AppDrawer from "./nav/AppDrawer.vue";
import { device } from "tns-core-modules/platform";
export default {
components: {
AppDrawer,
},
data() {
return {
msg:
"Vous n'êtes pas connecté. Les téléversements seront assigné avec l'ID: " +
device.uuid,
};
},
methods: {},
};
</script>
History.vue:
<template>
<Frame>
<Page>
<ActionBar>
<GridLayout width="100%" columns="auto, *">
<Label
text="MENU"
#tap="$refs.drawer.nativeView.showDrawer()"
col="0"
/>
<Label class="title" text="History" col="1" />
</GridLayout>
</ActionBar>
<RadSideDrawer ref="drawer">
<AppDrawer />
<GridLayout ~mainContent columns="*" rows="*">
<TextView editable="false">
<FormattedString>
<Span text="testing 1, 2" />
</FormattedString>
</TextView>
</GridLayout>
</RadSideDrawer>
</Page>
</Frame>
</template>
<script>
import AppDrawer from "./nav/AppDrawer.vue";
export default {
components: {
AppDrawer,
},
data() {
return {};
},
methods: {},
};
</script>
EDIT:
Ok, I understand the problem is that I import AppDrawer in App, so the App page have a menu. And I then import App in AppDrawer, because I want a "Home" button in the menu, so the user can return the the main page/screen.
This create a loop. I still don't understand how people import menus on each page and still have each page imported in the menu so user can be redirected on that page.
Based on the answer below, I tried:
<script>
export default {
components: {
App: () => import("../App.vue"),
AddProduct: () => import("../Add2.vue"),
History: () => import("../History.vue")
},
methods: {
btnHome() {
this.$navigateTo(App);
},
btnAdd2() {
this.$navigateTo(Add2);
},
btnHistory() {
this.$navigateTo(History);
}
}
};
</script>
But I get JS: [Vue warn]: Error in v-on handler: "ReferenceError: Add2 is not defined".
You are importing AppDrawer in App, and importing App in AppDrawer.vue, this import loop never end, you have to use lazyloading if you need do this (Although you imported and didnt use App componenet):
// in AppDrawer.vue
components: {
'App': () => import('../App.vue')
},

Nativescript vue tooltip use

I'm using nativescript vue
I want to run this tooltip.
code like in tutorial is not working:
<Button text="Get Json Data" id="tool" ref="tooltip" #tap="getData" class="btn btn-primary m-t-20"></Button>
I made button like this and in created trying to make it working but
created() {
let tipref = this.$refs.tooltip;
let tippref = this.$refs.page.tooltip;
//new ToolTip(this.nativeView.topmost().tip,{text:"Text"});
//const tip = new ToolTip(this.nativeView.tipref,{text:"Some Text"});
new ToolTip(tipref,{text:"Some Text"});
},
still not working: TypeError: Cannot read property 'tooltip' of undefined
TypeError: Cannot read property 'nativeView' of undefined
Can't figure out how to do it.
The code from the answer How to create a floating help layout? is not working too.
In order to access the NativeScript View via ref, you should do this.$refs.tooltip.nativeView. Also wait for the loaded event of the element to make sure it's ready to use.
<template>
<Page class="page">
<ActionBar title="Home" class="action-bar"/>
<ScrollView>
<StackLayout class="home-panel">
<Button
text="Get Json Data"
ref="tooltip"
class="btn btn-primary m-t-20"
#loaded="onLoaded"
></Button>
</StackLayout>
</ScrollView>
</Page>
</template>
<script>
export default {
data() {
return {};
},
methods: {
onLoaded: function(args) {
const ToolTip = require("nativescript-tooltip").ToolTip;
const tip = new ToolTip(args.object, {
text: "Some Text",
backgroundColor: "pink",
textColor: "black"
});
tip.show();
}
}
};
</script>