I am trying to do a simple to do app that does a request to a pokemon api and send me the result.
like this:
<template>
<div id="app">
<div>{{pokemon.forms}}</div>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "app",
data() {
return {
pokemon: {}
};
},
methods: {
requestPokemon() {
return new Promise((resolve, reject) => {
axios.get("http://pokeapi.co/api/v2/pokemon/2").then(value => {
resolve(value);
})
.catch(error => {
reject(error);
})
});
}
},
beforeMount() {
this.requestPokemon().then(value => {
pokemon = value;
}).error(error => {
console.log(error);
})
}
};
</script>
<style>
</style>
the issue is that i get the following error:
Error in beforeMount hook: "TypeError: this.requestPokemon(...).then(...).error is not a function"
any help with this??
thanks
Replace error with catch, as the others said:
export default {
name: "app",
data() {
return {
pokemon: {}
};
},
methods: {
requestPokemon() {
return new Promise((resolve, reject) => {
axios.get("http://pokeapi.co/api/v2/pokemon/2").then(value => {
resolve(value);
})
.catch(error => {
reject(error);
})
});
}
},
beforeMount() {
this.requestPokemon().then(value => {
pokemon = value;
}).catch(error => {
console.log(error);
})
}
};
Your beforeMount is not correct.
As oMiKeY said in his answer, you need to change .error to .catch
You also need to bind the response to this.pokemon (and not just pokemon)
Then, as requestPokemon function returns a Promise, you need to find the data in it :
beforeMount() {
this.requestPokemon().then(value => {
this.pokemon = value.data
}).catch(error => {
console.log(error);
})
}
Related
I use two functions to load some components for my page and save it in two fields representatives and allUsers. Then I try to use additional func subtractSets() to a little bit modify loaded data. My problem is that fields this.representatives and this.allUsers in this adittional function are still not initialized. What I can do to get loaded data in subtractSets()?
setup() {
const representatives = ref([])
const allUsers = ref([])
data() {
return {
representatives,
users
}
}
},
methods(): {
loadUsersRepresentatives() {
axios.get('getRepresentatives').then(res => {
this.representatives = res.data
}).catch(() => {
...
})
});
},
loadAllUsers() {
axios.get('/getAllUsers').then(res => {
this.allUsers = res.data
}).catch(() => {
...
})
});
},
subtractSets(obj1, obj2) {
...
},
showRepresentativesDialog(facultyID) {
this.loadUsersRepresentatives(facultyID)
this.loadAllUsers()
this.subtractSets(this.representatives, this.allUsers)
this.representativesDialog = true
}
},
´´´
You are missing async / await
methods(): {
async loadUsersRepresentatives() {
return axios.get('getRepresentatives').then(res => {
this.representatives = res.data
}).catch(() => {
...
})
});
},
async loadAllUsers() {
return axios.get('/getAllUsers').then(res => {
this.allUsers = res.data
}).catch(() => {
...
})
});
},
subtractSets(obj1, obj2) {
...
},
async showRepresentativesDialog(facultyID) {
await this.loadUsersRepresentatives(facultyID)
await this.loadAllUsers()
this.subtractSets(this.representatives, this.allUsers)
this.representativesDialog = true
}
},
I create check-in system (Laravel + Vuetify), so i would like to ask: how to get userID from an object (API) en put them into input?
<template>
<v-text-field
v-model="debugItem.extra1_int"
:counter="250"
label="extra1_int"
hint="userID"
type="number"
clearable>
</v-text-field>
</template>
<script>
export default {
data() {
return {
debugItem: {}, /* store new debugItem */
user: '',
}
},
mounted() {
this.getUser();
this.debugItem.extra1_int = ***how to put here userID?***;
},
methods: {
getUser() {
axios.get('/user')
.then(response => (this.user = response.data))
.catch(error => console.log(error));
},
addDebugItem() { /* store new debugItem */
this.axios
.post('/api/debugs', this.debugItem)
.then(response => (
this.$router.push({name: 'indexDebugs'})
))
.catch(err => console.log(err))
.finally(() => this.loading = false)
}
}
}
</script>
Method getUser() http://127.0.0.1:8000/user return json-object of logged user:
{
"id": 119,
"name": "Johan",
"email": "Johan#mail.com",
"email_verified_at": null,
"is_active": 1,
"created_at": "2022-05-09T14:24:48.000000Z",
"updated_at": "2022-05-09T14:24:48.000000Z"
}
Thanks.
<template>
<v-text-field
v-model="debugItem.userId"
:counter="250"
label="extra1_int"
hint="userID"
type="number"
clearable>
</v-text-field>
</template>
<script>
export default {
data() {
return {
debugItem: {userId: null}, /* store new debugItem */
user: '',
}
},
mounted() {
this.getUser();
this.debugItem.userId = this.user.id
},
methods: {
getUser() {
axios.get('/user')
.then(response => (this.user = response.data))
.catch(error => console.log(error));
},
addDebugItem() { /* store new debugItem */
this.axios
.post('/api/debugs', this.debugItem)
.then(response => (
this.$router.push({name: 'indexDebugs'})
))
.catch(err => console.log(err))
.finally(() => this.loading = false)
}
}
}
</script>
My suggestion, Instead of assigning value to this.debugItem.extra1_int in mounted() lifecycle hook. You can assign it in getUser() on success of axios call.
data() {
return {
debugItem: {},
user: '',
}
},
mounted() {
this.getUser();
this.debugItem.extra1_int = ***how to put here userID?***; ❌
},
methods: {
getUser() {
axios.get('/user')
.then(response => {
this.user = response.data;
this.debugItem['extra1_int'] = this.user.id; ✅
})
.catch(error => console.log(error));
}
}
Main view:
<script>
import { testMethod1 } from "../helper";
export default {
methods: {
init(){
console.log("Res:", testMethod1());
}
}
}
</script>
Helper:
import DataService from "../services/data.service";
export function testMethod1() {
DataService.getByPage()
.then((response) => {
console.log(response)
return response;
})
.catch((error) => {
console.log(error);
})
}
Output:
From view:
Res: undefined
From helper:
0: {_id: "60b621b4809e4304e04e7df4", desc: "aaa", …}
1: {_id: "60b621b4809e4304e04e7df5", desc: "bbb", …}
(..)
What am I doing wrong?
// See this is the same error
const incorrectFoo = () => {
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => json)
}
const correctFoo = () => {
return fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => json)
}
const someOtherFoo = async () => {
console.log('incorrect foo', await incorrectFoo(), 'correctFoo', await correctFoo())
}
someOtherFoo()
This method is executing a async call,
export function testMethod1() {
DataService.getByPage()
.then((response) => {
console.log(response)
return response;
})
.catch((error) => {
console.log(error);
})
}
Now if you notice DatasService is a async call and that async call get to another context where it whenever get resolved returns response which mean testMethod1 is not returning anything any way try this
export function testMethod1() {
return DataService.getByPage()
.then((response) => {
console.log(response)
return response;
})
.catch((error) => {
console.log(error);
})
}
<script>
import { testMethod1 } from "../helper";
export default {
methods: {
async init(){
console.log("Res:", await testMethod1());
}
}
}
</script>
After importing the method from helper, you need also to declare it in methods section like:
<script>
import { testMethod1 } from "../helper";
export default {
methods: {
testMethod1, // this is same with testMethod1: testMethod1,
init(){
console.log("Res:", this.testMethod1());
}
}
}
</script>
I've got a nativescript vue application, and on a certain page I need to fetch some data (every 3 seconds) from an api using axios. The data is returned in xml, and I convert it to json using xml2js. I'm using async/await for both these functions. Something is blocking the UI thread, because whenever this function runs scrolling in my app freezes, along with any animations.
Does anyone know what here is blocking the DOM?
<template>
//ui code here
</template>
<script>
import { mapGetters } from 'vuex'
import axios from 'axios'
import xml2js from 'nativescript-xml2js'
export default {
name: 'component1',
data () {
return {
pending: true,
error: false,
results: null,
refreshInterval: null
}
},
computed: {
...mapGetters({
token: 'main/token'
})
},
methods: {
async requestData() {
const headers = {
Cookie: 'USER_ID=' + this.token
}
const url = 'url goes here'
const parser = new xml2js.Parser({
async: true
})
try {
const response = await axios.get(url, { headers: headers })
const newData = await new Promise((resolve, reject) => parser.parseString(response.data, (err, result) => {
if (err) reject(err)
else resolve(result)
}))
this.results = newData['results']
this.error = false
this.pending = false
} catch (e) {
this.data = null
this.error = e
this.pending = false
}
this.pending = false
}
},
created() {
setTimeout(() => {
this.requestData()
},500)
this.refreshInterval = setInterval(() => {
this.requestData()
},3000)
},
beforeDestroy () {
clearInterval(this.refreshInterval)
}
}
</script>
EDIT:
I tried implementing workers to offload xml2js to another thread, but still having the same issue. This is how my code looks now:
home.vue:
<template>
<template/>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'component1',
data () {
return {
dataLoaded: true,
error: false,
results: null,
refreshInterval: null
}
},
computed: {
...mapGetters({
token: 'main/token'
})
},
methods: {
requestData() {
console.log('fetching....')
this.$backendService
.api()
.then(xml => {
return this.$backendService.x2jworker(xml)
})
.then(json => {
if( this.results !== json['results'] ) {
this.results = json['results']
}
this.dataLoaded = true
this.error = false
})
.catch((error) => {
this.dataLoaded = true
this.error = true
})
}
},
created() {
setTimeout(() => {
this.requestData()
},500)
this.refreshInterval = setInterval(() => {
this.requestData()
},3000)
},
beforeDestroy () {
clearInterval(this.refreshInterval)
}
}
</script>
backend-service.js:
import axios from 'axios';
import xml2js from 'nativescript-xml2js'
import { WorkerService } from "../worker.service"
export default class BackendService {
api() {
return new Promise((resolve, reject) => {
const url = 'url'
axios.get(url)
.then(response => {
resolve(response.data)
})
.catch((error) => {
if (error) {
console.log('uh oh')
reject(error)
}
})
})
}
x2jworker(xml) {
return new Promise((resolve, reject) => {
var workerService = new WorkerService()
var jsWorker = workerService.initJsWorker()
jsWorker.onmessage = m => {
resolve(m.data)
}
jsWorker.postMessage(xml)
jsWorker.onerror = e => {
console.log(e)
jsWorker.terminate()
reject(e)
}
})
}
}
worker/javascript.worker.js:
import 'tns-core-modules/globals'
import xml2js from 'nativescript-xml2js'
global.onmessage = function (msg) {
console.log("Inside JS worker...")
var parser = new xml2js.Parser({
async: true
})
parser.parseString(msg.data, function (err, result) {
if (err) {
console.log(err)
global.close()
} else {
global.postMessage(result)
}
})
}
worker-service.js:
const workers = []
export class WorkerService {
constructor() {
}
initJsWorker() {
if (this.jsWorker) {
return this.jsWorker
}
const JsWorker = require("nativescript-worker-loader!./workers/javascript.worker.js")
this.jsWorker = new JsWorker()
workers.push(this.jsWorker)
return this.jsWorker
}
}
if ((module).hot) {
(module).hot.dispose(() => {
workers.forEach(w => {
w.terminate()
})
})
}
Our code currently has a function that calls a toast message popup while saving an object to the database.
export function addAnimal(animalObject) {
return function(dispatch) {
showToastNotification(() => {
return addAnimal(animalObject);
}, dispatch);
};
}
function showToastNotification(handleToastSave, dispatch) {
return handleToastSave()
.then(() => {
showMessage("this was a success")(dispatch);
})
.catch(() => {
showMessage("Something went wrong!")(dispatch);
})
.finally(() => {
saveMode(false)(dispatch);
});
}
My question is I want to pass a message string as a parameter to the showToastNotification like this:
export function addAnimal(animalObject) {
return function(dispatch) {
showToastNotification(("successfully added animal") => {
return addAnimal(animalObject);
}, dispatch);
};
}
function showToastNotification(message, handleToastSave, dispatch) {
return handleToastSave()
.then(() => {
showMessage(message)(dispatch);
})
.catch(() => {
showMessage("Something went wrong!")(dispatch);
})
.finally(() => {
saveMode(false)(dispatch);
});
}
This doesn't work. I'm not super familiar with how the fat arrow in this function works. Would it be possible to pass a prop to showToastNotification?
You're putting the string where the parameters of the callback would be, instead of as the first argument to the actual showToastNotification function. Just move it to the right place:
showToastNotification("successfully added animal", () => {
return addAnimal(animalObject);
}, dispatch);