Unable to access `get` method in vue-resource - vue.js

I have a tiny vue app where I'm wanting to use vue-resource to request an api endpoint.
I've installed vue-resource via npm
I've added the Vue.use(VueResource) lines to my bootstrap file
I've setup my component like this to call the .get method
Blog.vue
...
mounted () {
this.fetchPosts()
},
methods: {
fetchPosts: () => {
debugger;
this.$http.get('my-url')
.then(response => {
console.log(response)
})
}
}
...
I've seen a few github issues and SO posts which touch on this type of problem but most seem to relate to incorrect configuration which I don't think I have (happy to be proven wrong!)
The specific console error I get is:
Error in mounted hook: "TypeError: Cannot read property 'get' of undefined"
What's odd about this is that if you see my debugger line, if I console.log this.$http.get at that point I get:
function (url, options$$1) {
return this(assign(options$$1 || {}, {url: url, method: method$$1}));
}
If I let the code run and then attempt the console.log afterwards I get:
Cannot read property 'get' of undefined
As a result I presume it's some kind of this context issue, but from what I can see the reference should be correct...shouldn't it?

Methods should not be arrows function. The this will not point to the vue instance if a methods is declared using arrow function.
Use normal function instead:
methods: {
fetchPosts(){
debugger;
this.$http.get('my-url')
.then(response => {
console.log(response)
})
}
You can see the warning here

Related

Vue 2 / Nuxt 2 Emit From Axios With Dialog Confirm

i am using Vue 2 / nuxt to emit from a axios post* call which itself is called from a Buefy dialog confirm. The emit from this component will close the window / panel and then re-load the users.
If I call the axios request from the button, this works without any issues, but once being called from the dialog, it just don't work?
*most likely this will be updated to a delete request, just not gotten to that let
See code below:
removeUser() {
this.$buefy.dialog.confirm({
message: 'Continue on this task?',
onConfirm: () => {
this.removeUserFunc()
}
})
},
removeUserFunc() {
// console.log(that)
const that = this
// Build URL
const EndPoint = '/remove_user/' + this.id
this.$axios.post(EndPoint).then((res) => {
// User Remove Message
UserRemoved(this.$swal)
that.$parent.$emit('completed')
// console.log(this.$emit('complete'))
// // Emit 'completed' Message
console.log(that.$emit('completed'))
console.log(that)
}).catch((res) => {
console.log(res)
// Check For Errors
GeneralError(this.$swal)
})
}
I was thinking it was losing access to the correct this, so i was trying to pass that back in, but not sure that is the case?
I have also tried with await, while that sort of works? I think is firing the emit too fast, as it re-loads the users but it still includes the user that as just been deleted?
removeUser() {
this.$buefy.dialog.confirm({
message: 'Continue on this task?',
onConfirm: async() => {
this.removeUserFunc()
await this.$emit('completed')
}
})
},
The this keyword refers to the object the function belongs to, or the window object if the function belongs to no object.
Try to use .bind and use a ES5 function
removeUser() {
this.$buefy.dialog.confirm({
message: 'Continue on this task?',
onConfirm: function() {
this.removeUserFunc()
}.bind(this)
})
},

Cannot read properties of undefined (reading 'element') when accessing event object

So I am using Vue Draggable and I am to access the event object in VueJs like below:
<draggable group="leads"
:list="newLeads"
#change="seeChange($event, 'New')">
In methods:
async seeChange(event, status) {
console.log(event.added.element.id);
await axios.patch('http://localhost/api/leads/'+event.added.element.id+'/update-status',
{status : status}).then(response => {
this.leads.unshift(response.data.data);
this.getLeads();
}).catch(error => {
console.log(error);
});
},
I can see the id in the console. But when I drag the card (triggering the event) I get a
Cannot read properties of undefined (reading 'element')
error when the card lands. Even the Axios call gets the correct id and the request is sent fine. But the white screen with this error appears nonetheless.
What am I missing?
Change event is called with one argument containing one of the following properties: added, removed, moved. Docs.
event.added contains information of an element added to the array but when you do removed, moved you haven't property added in object event.
You can use it like this:
async seeChange(event, status) {
console.log(event?.added.element.id);
if(event.added) {
await axios.patch('http://localhost/api/leads/'+event.added.element.id+'/update-status', {status : status}).then(response => {
this.leads.unshift(response.data.data);
this.getLeads();
}).catch(error => {
console.log(error);
});
}
}
request will be send only after added event.
If you want to send request on each event you can do it
by using Object.values(event)[0], example:
async seeChange(event, status) {
const id = Object.values(event)[0].element.id;
console.log(id);
await axios.patch('http://localhost/api/leads/'+id+'/update-status', {status : status}).then(response => {
this.leads.unshift(response.data.data);
this.getLeads();
}).catch(error => {
console.log(error);
});
}
in vue 3 you should use draggable library as below:
install:
npm i -S vuedraggable#next
import:
import Draggable from 'vuedraggable';
and this is the link with full examples:
https://github.com/SortableJS/vue.draggable.next

express fetch promise will not resolve before render

I have an express route and I want to send back the result of a fetch to my pug template. I know my fetch URL works as I have checked it with postman and the data comes back as it should. I would like to store the fetch of the result to the variable called weather at the bottom of the route. My template looks for this variable to exist before adding weather to the template
I have also logged my form data to make sure the form is sending the data to my express server
I get this error in my command console when logging the return:
Promise { <pending> }
(node:18060) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'json' of undefined
I think the issue must be with my promise structure or perhaps it has to do with CORS not being enabled in my app? I'm not getting any errors and I'm hoping someone might have an answer for me??
router.post("/", async(req, res, next)=>{
console.log(req.body.selectedCity)
console.log(req.body.selectedState)
console.log(req.body.selectedZip)
var result = await fetch(`http://api.openweathermap.org/data/2.5/weather?q=${req.body.selectedCity}&units=imperial&appid=${apiKey}`)
.then(function(result) {
console.log(result.json())
})
.then((result)=>{
console.log(result.json())
res.render('index', {states:[
{
id:"none",
name:"choose"
},
{
id:"OH",
name:"Ohio"
},
{
id:"UT",
name:"Utah"
},
{
id:"VT",
name:"Vermont"
},
{
id:"VA",
name:"Virginia"
},
{
id:"WA",
name:"Washington"
},
{
id:"WV",
name:"West Virginia"
},
{
id:"WI",
name:"Wisconsin"
},
{
id:"WY",
name:"Wyoming"
}
],weather:result})
})
});
You have an uncorrect syntax on async/await.
You do not use .then in async/await but you just await the promise and store the result in a variable.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
var result = await fetch(`http://api.openweathermap.org/data/2.5/weather?q=${req.body.selectedCity}&units=imperial&appid=${apiKey}`)
.then(function(result) {
console.log(result.json())
})
.then((result)=>{
console.log(result.json())
res.render [...]
Becomes:
const result = await fetch(`http://api.openweathermap.org/data/2.5/weather?q=${req.body.selectedCity}&units=imperial&appid=${apiKey}`);
console.log(result.json())
res.render [...]
Try and avoid var as it may lead to unexpected behavior.
Try using axios as a fetch library, it's much cleaner than fetch.
https://www.npmjs.com/package/axios
This way it's just const result = await axios.get([...]
This should be structured this way instead -
fetch('url')
.then(result=>result.json)
.then(result=>res.render())
You should also remove async keyword from the callback function provide to router.post.

Framework 7 Vue2: Error in Mounted Hook for this.$f7

I'm trying to use the Framework 7 api for
this.$f7.showPreloader()
mounted() {
this.getPosts();
},
methods: {
getPosts() {
this.$f7.showPreloader();
var self = this
axios.get('http://jsonplaceholder.typicode.com/posts')
.then(response => {
self.posts = response.data
self.$f7.hidePreloader();
})
.catch(e => {
this.errors.push(e)
})
},
When the app loads, it gives a Error in mounted hook: "TypeError: this.$f7 is undefined". However when I call it as a #click event, it works
clickme() {
this.getPosts();
},
How do I call the F7 api object from the mounted event hook correctly?
Ok, this may not be the final answer but this is the best I got.
There is a special hook for f7 Vue called
methods: {
onF7Init: function () {
//do some code here
});
}
}
This a special hook that occurs after F7 framework has been init after mounted. Put it in your methods. Apparently nobody wrote this in the documentation. If you put window.f7 here, the object will be defined and you can use it.

RTCPeerConnection.createAnswer callback returns undefined object in mozilla for WebRTC chat

Following is my code to answer the incoming call:
var pc = connection.pc;
pc.setRemoteDescription(sdp,function() {
pc.createAnswer(function(answer) {
pc.setLocalDescription(answer,function() {
// code for sending the answer
})
})
})
The above code works fine for chrome, but when i run the same in mozilla, the answer obtained from pc.createAnswer callback is undefined. As a result of which it gives me following error:
TypeError: Argument 1 of RTCPeerConnection.setLocalDescription is not
an object.
The problem is you're not checking errors, specifically: not passing in the required error callbacks.
setRemoteDescription and setRemoteDescription require either three arguments (legacy callback style) or one (promises), but you're passing in two. Same for createAnswer minus one.
The browser's JS bindings end up picking the wrong overload, returning you a promise which you're not checking either, effectively swallowing errors.
Either add the necessary error callbacks:
var pc = connection.pc;
pc.setRemoteDescription(sdp, function() {
pc.createAnswer(function(answer) {
pc.setLocalDescription(answer, function() {
// code for sending the answer
}, function(e) {
console.error(e);
});
}, function(e) {
console.error(e);
});
}, function(e) {
console.error(e);
});
Or use the modern promise API:
var pc = connection.pc;
pc.setRemoteDescription(sdp)
.then(() => pc.createAnswer())
.then(answer => pc.setLocalDescription(answer))
.then(() => {
// code for sending the answer
})
.catch(e => console.error(e));
The promise API is available natively in Firefox, or through adapter.js in Chrome. See fiddle.
And always check for errors. ;)