Set data from method in vuejs - javascript

I am trying to set an data from a method. I am using fetch to get an rest data. But, when I try to set the data, using this.item = 'test' doesn't work. So, when my this.item is inside ".then" doesn't working. But when is out of ".then" it working... But I need to use a rest call to get the data...
Vue.component('internal_menu', {
props: ['list'],
data: function () {
return {
item: '1'
}
},
methods: {
teste(event)
{
event.preventDefault();
var payload = {
method: 'GET',
headers: { "Accept": "application/json; odata=verbose" },
credentials: 'same-origin' // or credentials: 'include'
}
const url = _spPageContextInfo.webAbsoluteUrl +
"/_api/Web/Lists/GetByTitle('"+ this.list +"')/Items?
$select=Title,Id,Link,Icone&$orderby=Title%20asc";
fetch(url,payload)
.then((resp) => resp.json())
.then(function(data)
{
let items = data.d.results;
this.item = 'teste';// this not working here
})
. catch(function(error) {
console.log(JSON.stringify(error));
});
this.item = 'tst123'; //this working here
},
},
template: `
<div id='tst'>
<h3>{{list}} - {{item}}</h3>
<button v-on:click="teste">Try Me</button>
</div>
`,
mounted: function () {
this.getMenuData();
}
})
new Vue({
el: "#app"
})
thanks
Everton

When you do this:
.then(function(data)
{
let items = data.d.results;
this.item = 'teste';// this not working here
})
Your closure's reference to this is the within the context of the anonymous function. Instead, you need to use the fat arrow function in order to maintain the context of the Component.
.then((data) => {
let items = data.d.results;
this.item = 'test';
})

Related

Cascading Dropdown - How to load Data?

I try to make an cascading dropdown, but I have problems with the sending and fetching of the response data.
Backend:
[HttpPost]
public async Task<JsonResult> CascadeDropDowns(string type, int id)
{ .............
return Json(model);
}
Here I get the correct data.
First I tried:
$("#dropdown").change( function () {
var valueId = $(this).val();
var name = $(this).attr("id");
let data = new URLSearchParams();
data.append("type", name);
data.append("id", valueId);
fetch("#Url.Action("CascadeDropDowns", "Home")", {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
},
body: data
})
.then(response => {
console.log('Success:', response);
return response.json();
})
.then(json => {
console.log('Success:', json );
console.log('data:', json.Projects);
PopulateDropDown("#subdropdown1",json.Projects)
})
.catch(error => {
console.log('Error:', error);
});
});
Here I can send the Request and get a "success" back. However, when I access json.Projects I just get an `undefined. I have tried to change the Content-Type, without success.
Secondly I have used:
$.ajax({
url: "#Url.Action("CascadeDropDowns", "Home")",
data: data,
type: "POST",
contentType: "application/x-www-form-urlencoded;charset=UTF-8",
success: function (data) {
console.log(data);
},
error: function (r) {
console.log(r.responseText);
},
failure: function (r) {
console.log(r.responseText);
}
});
With this I get an Illegal Invocation Error.
What do I have to do that get either of those working? What are their problems?
I try to make an cascading dropdown, but I have problems with the
sending and fetching of the response data.What do I have to do that get either of those working? What are their problems?
Well, let consider the first approach, you are trying to retrieve response like json.Projects but its incorrect because data is not there and you are getting undefined as below:
Solution:
Your response would be in json instead of json.Projects
Complete Demo:
HTML:
<div class="form-group">
<label class="col-md-4 control-label">State</label>
<div class="col-md-6">
<select class="form-control" id="ddlState"></select>
<br />
</div>
</div>
Javascript:
var ddlState = $('#ddlState');
ddlState.empty();
ddlState.append($("<option></option>").val('').html('Please wait ...'));
let data = new URLSearchParams();
data.append("type", "INDIA");
data.append("id", 101);
fetch("http://localhost:5094/ReactPost/CascadeDropDowns", {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
},
body: data
})
.then(response => {
return response.json();
})
.then(result => {
console.log(result);
var ddlState = $('#ddlState');
ddlState.empty();
ddlState.append($("<option></option>").val('').html('Select State'));
$.each(result, function (index, states) {
ddlState.append($("<option></option>").val(states.cityId).html(states.cityName));
});
})
Second approach:
In ajax request you are passing object as object fahsion like data: data whereas, your controller expecting as parameter consequently, you are getting following error:
Solution:
You should pass your data within your ajax request like this way data: { type: "YourTypeValue", id:101 }, instead of data: data,
Complete Sample:
$.ajax({
url: 'http://localhost:5094/ReactPost/CascadeDropDowns',
type: 'POST',
data: { type: "YourValue", id:101 },
success: function (response) {
ddlState.empty();
ddlState.append($("<option></option>").val('').html('Select State'));
$.each(response, function (i, states) {
ddlState.append($("<option></option>").val(states.cityId).html(states.cityName));
});
},
error: function (response) {
alert('Error!');
}
});
Note: I have ommited contentType because, by default contentType is "application/x-www-form-urlencoded;charset=UTF-8" if we don't define.
Output:

How to populate component's data with axios method in Vue.JS

I want to populate a component data using a method with Axios. However, with Axios, the component data is always undefined. If I don't use Axios (hardcode the return value), the component data populates correctly.
data () {
return {
myData: this.getData();
}
},
methods:{
getData(){
axios({
method: 'GET',
url : 'Department/GetAllForDropdown',
}).then(function (response){
return response.data;
});
}
}
How do I achieve this without using the conventional way of populating, e.g.
.then(function (response){
self.myData = response.data;
})
Thank you.
=======EDIT========
I have a dynamic form builder. I am using vuetify. It creates the form components from the data I have declared.
<template>
<div v-for="formItem in formDetails.formInfo">
<v-text-field
v-if="formItem.type != 'select'
:label="formItem.placeholder"
v-model="formItem.value"
></v-text-field>
<v-select
v-if="formItem.type == 'select'
:items="formItem.options"
:label="formItem.placeholder"
v-model="formItem.value"
></v-select>
</div>
</template>
data () {
return {
formDetails: {
title: 'myTitle',
formInfo:[
{
type:'text',
placeholder:'Name*',
value: '',
},
{
type:'select',
placeholder:'Option1*',
options: this.getOptions1(),
value: '',
},
{
type:'select',
placeholder:'Option2*',
options: this.getOptions2(),
value: '',
},
]
},
}
},
methods:{
getOptions1(){
var self = this;
axios({
method: 'GET',
url : 'Department1/GetAllForDropdown',
}).then(function (response){
return response.data;
});
},
getOptions2(){
var self = this;
axios({
method: 'GET',
url : 'Department2/GetAllForDropdown',
}).then(function (response){
return response.data;
});
}
}
I am currently stuck at making the select box dynamic, because I plan to pass in the options like
options: this.getOptions1(),
for them to get all the options in the select box.
Thank you.
The idea is still assigning the response to the item and leave a placeholder while loading.
getOptions(formItem) {
formItem.loading = true;
var placeholder = formItem.placeholder;
formItem.placeholder = "Loading... Please wait";
axios({
method: "GET",
url: "Department1/GetAllForDropdown"
}).then(function(response) {
formItem.loading = false;
formItem.placeholder = placeholder;
formItem.options = response.data;
});
}
I write a small demo. You could try it out.

How to save data in Vue instance

The question is quite simple,
All I want is to get the data after the AJAX post saved in Vue instace's data.
Here is my code:
const VMList = new Vue({
el: '#MODAL_USER_DATA',
data: {
user: []//,
//userAcc: []
},
methods: {
getUserAcc: function ( userID ) {
this.user = { _id : userID };
var self = this
$.ajax({
url: "/listuser",
type: "POST",
data: this.user,
success: function(data) {
this.user = data ;
//this.userAcc = Object.assign({}, this.userAcc, data );
alert(JSON.stringify(this.user));//show the user correctly (e.g user = data)
$('#popupDeleteModal').modal('show');
alert(JSON.stringify(data));//show data,the entire json object,everything is good
},
error: function(err) {
console.log('error: ',err);
},
});
}
}
});
And after I trigger the getUserAcc(id) method,I try to verify the VMList.user value in browser console,and I get only the id.Seems like after the function is over the data is reset.How could I store the data from the AJAX post request in the user object from data:{...} ?
Thank you for help!!!
The problem is that this inside your ajax return function doesn't refer to the vue instance anymore.
The solution is to save the this keyword into a variable inside the function. Example:
getUserAcc: function ( userID ) {
var that = this;
this.user = { _id : userID };
$.ajax({
url: "/listuser",
type: "POST",
data: this.user,
success: function(data) {
that.user = data;
//Rest of your code
},
error: function(err) {
console.log('error: ',err);
},
});
}
Here is more information about the behavior of the keyword this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

Property or method "orgs" is not defined on the instance but referenced

I am using vue2 and I am trying to fetch an api and render the contents in my page, this is all done in my Orgs.vue file and here is the code:
<template lang="html">
<div class="">
{{ orgs | json }}
</div>
</template>
<script>
export default {
data: {
orgs: false
},
created() {
request = axios({
url: 'https://....',
method: 'GET',
})
.then(function(response) {
this.orgs = response;
})
.catch(function(error) {
console.log('error getting orgs::', error);
});
}
};
</script>
<style lang="css">
</style>
However everytime I run the page I get this error:
Property or method "orgs" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. found in Orgs.vue
I tried to change
data: {
orgs: false
},
to
data() {
return {orgs: false}
},
but the error is still there
You need save vue instance reference in variable before making request and use it to access vue in response handler. I used vue_instance in example.
And for components init data as function.
data: function() {
return {
orgs: false
}
},
created() {
var vue_instance = this;
request = axios({
url: 'https://....',
method: 'GET',
})
.then(function(response) {
vue_instance.orgs = response.data;
})
.catch(function(error) {
console.log('error getting orgs::', error);
});
}
EDIT: In axios response handler this is reference on window. Axios don't know anything about vue.

Vue.js 2: Get data from AJAX method

I'm new to Vue, and I'm attempting to grab the data via AJAX in a method.
I know the method is working.
Here's the Vue code:
Vue.component('sub-folder', {
props: ['folder'],
template: '{{folder.title}}'
});
var buildFoldersList = new Vue({
el: '#sub-folders',
data: {
foldersList: this.foldersList
},
methods: {
buildFolders: function () {
$.ajax({
url: base_url + 'api/folder/get_subfolders/' + browser_folder_id,
method: 'POST',
data: {
"folder_id": browser_folder_id
},
success: function (data) {
console.log("Data");
console.log(data);
this.foldersList = data;
},
error: function (error) {
alert(JSON.stringify(error));
}
});
}
}
});
Here's the HTML:
<div class="list-group" id="sub-folders">
<sub-folder v-for="folder in foldersList" :key="folder.folder_id" v-bind:folder="folder"></sub-folder>
</div>
At the moment, the containing template is running, but since the method isn't getting executed, there's no data.
I've tried everything I know to trigger the method, but I've run out of ideas.
It seems you are not calling the buildFolders method at all, you can call it from the created hook of vue.js like following:
var buildFoldersList = new Vue({
el: '#sub-folders',
data: {
foldersList: []
},
created () {
this.buildFolders()
},
methods: {
buildFolders: function () {
var self = this
$.ajax({
url: base_url + 'api/folder/get_subfolders/' + browser_folder_id,
method: 'POST',
data: {
"folder_id": browser_folder_id
},
success: function (data) {
console.log("Data");
console.log(data);
self.foldersList = data;
},
error: function (error) {
alert(JSON.stringify(error));
}
});
}
}
});
Also you can relook at how you are using this, as scope of this will change in $.ajax method as happened here, see the explanation here.

Categories

Resources