Back4app Parse-sever : Find just get just the id not all data - vue.js

Im on a find situacion because the result of the Parse.query is just the id and I had other columns :(
Response of find:
[{"_objCount":0,"className":"DivorceCase","id":"8Ab15ASBX3"}]
Actual Code:
// Your corresponding keys
Parse.initialize("xxx", "xxx");
// For back4app applications
Parse.serverURL = 'https://parseapi.back4app.com'
var app = new Vue({
el: "#AttorneyCases",
data: {
DivorceCase :{},
},
mounted:function(){
new Parse.Query("DivorceCase").descending("createdAt").find()
.then((DivorceCaseResponse) => {
this.DivorceCase = DivorceCaseResponse;
})
}
})

to get the value of the other columns field, you need to use the code below:
var columnName = DivorceCaseResponse.get("columnName");
You can check more about retrieving objects here.

Thanks, nataliec!
The final code is:
mounted: function() {
var Case = Parse.Object.extend("DivorceCase");
var query = new Parse.Query(Case);
query.find()
.then((Ids) => {
Ids.forEach(element => {
var Case = Parse.Object.extend("DivorceCase");
var query = new Parse.Query(Case);
query.get(element.id)
.then((DivorceCaseResponse) => {
// The object was retrieved successfully.
this.DivorceCases.push(DivorceCaseResponse.get("BasicInfo"));
},
(e) => {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and message.
swal({
position: 'center',
type: 'error',
title: e.message,
customClass: 'swal-wide'
})
});
});
},
(e) => {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and message.
swal({
position: 'center',
type: 'error',
title: e.message,
customClass: 'swal-wide'
})
});
}

Related

How can I use this variable on Vue.js?

I have a problem trying to use a variable inside my async function in Vue
this is in methods:
methods: {
async editar(event) {
db.collection("products").doc(event).get().then((doc) => {
const productData = doc.data();
console.log("Nombre: ", productData.nombre); /* this */
console.log("Stock: ", productData.stock);
}).catch((error) => {
console.log("Error getting document:", error);
});
const alert = await alertController.create({
cssClass: 'alertClass',
header: 'Editar producto',
message: '¿Qué deseas cambiar?',
inputs: [
{
name: 'nuevoNombre',
type: 'text',
placeholder: 'Nombre',
value: '' /* here */
},
{
name: 'nuevoStock',
type: 'number',
placeholder: 'Stock'
}
],
buttons: [
{
text: 'Cancelar',
role: 'cancel',
cssClass: 'secondary',
handler: () => {
console.log('Cancelado');
},
},
{
text: 'Aceptar',
handler: (data) => {
console.log('Se actualiza el doc: ' + event);
db.collection("products").doc(event).update({
nombre: data.nuevoNombre,
stock: data.nuevoStock
}).then(() => {
console.log("Nuevo nombre:", data.nuevoNombre);
console.log("Nuevo stock:", data.nuevoStock);
window.location.reload();
}).catch((error) => {
console.log("Error al intentar cambiar los valores", error);
});
},
},
],
});
return alert.present();
}
}
I want to use productData.nombre in the value inside the alertController. I was trying a lot of things but nothing works :(
I hope you can understand my question
const productData = doc.data();
const defined productData only can be reference at cloest scope.
At your situation, scope is
db.collection("products").doc(event).get().then((doc) => {
const productData = doc.data(); // only referenced in this scope (arrow function)
console.log("Nombre: ", productData.nombre); /* this */
console.log("Stock: ", productData.stock);
})
You can define variable before give it a value like this
async function editar(event) {
let productData;
db.collection("products")
.doc(event)
.get()
.then((doc) => {
productData = doc.data();
console.log("Nombre: ", productData.nombre); /* this */
console.log("Stock: ", productData.stock);
})
.catch((error) => {
console.log("Error getting document:", error);
});
const alert = await alertController.create({
// your code
})
}
db.collection("products") seems like an async function, using await before calling it, or you will miss db data since it's not ready.
You should declare variable outside your function which getting db data first, due to javascript scope
Here is a similar easy example on codepen

VueJS array returns length = 0

I have created an array in my VueComponent.
When I run a console.log(myArray.length) it says "0", however if I run a console.log(myArray) it shows that the array has the expected data. Check the screenshot from console below. The first part shows myArray, the second is myArray.length (circled in red)
See screenshot
Here is my current code:
Vue.component('invoice-archive', {
data: function () {
return {
invoices: [],
}
},
created() {
this.myUpdateMethod();
},
methods:{
myUpdateMethod: function(){
var $this = this;
let data = { 'id': installationId };
this.getAjax('myUrlHere', data).then(function (result) {
if(!result.length ) return; // <-- This was the problem
$this.invoices.push(JSON.parse(result));
console.log($this.invoices); // This shows the expected content of my array
console.log($this.invoices.length); // This shows 0
});
},
getAjax(url, data, success) {
return new Promise(function (resolve, reject) {
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xhr.onload = function () {
resolve(this.responseText);
}
xhr.onerror = reject;
xhr.open('POST', url);
xhr.setRequestHeader('Content-Type', "application/json;charset=UTF-8");
xhr.send(JSON.stringify(data));
});
},
});
That is because when you are resolving the promise with this.responseText, you are passing a string into it. You will need to convert the response to JSON first, i.e.:
resolve(JSON.parse(this.responseText));
Since you're using VueJS, you might want to consider using axios instead of rolling your own AJAX request handler: https://v2.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html

Vuex - Normalizr doesn't work as expected

I am creating a simple chat app. I have three entities: rooms, messages and users.
I have a fake API that returns a response like this:
[{
id: 1,
name: 'room1',
avatar: 'some img url',
messages: [
{
id: 1,
text: 'some text',
user: {
id: 1,
username: 'Peter Peterson',
avatar: 'some img url'
}
]
}]
And my action looks like this:
getAllRooms({ commit }) {
commit(GET_ALL_ROOMS_REQUEST);
return FakeApi.getAllRooms()
.then(
rooms => {
const { entities } = normalize(rooms, room);
console.log(entities);
commit(GET_ALL_ROOMS_SUCCESS, {
rooms: entities.rooms, byId: rooms.map(room => room.id)
});
commit(GET_ALL_MESSAGES_SUCCESS, { messages: entities.messages });
commit(GET_ALL_USERS_SUCCESS, { users: entities.users });
},
err => commit(GET_ALL_ROOMS_ERROR)
)
}
And my mutations look like this:
[GET_ALL_ROOMS_REQUEST](state) {
state.loading = true;
},
[GET_ALL_ROOMS_SUCCESS](state, payload) {
state.rooms = payload.rooms;
state.byId = payload.byId;
state.loading = false;
},
[GET_ALL_ROOMS_ERROR]() {
state.error = true;
state.loading = false;
}
And my component calls the action like this:
{
mounted() {
this.getAllRooms();
}
}
These are my schema definitions:
const user = new schema.Entity('users');
const message = new schema.Entity('messages', {
user: user
});
const room = new schema.Entity('rooms', {
messages: [message]
})
when i check the response in then method after FakeApi.getAllRooms() every object is wrapped in some weird Observer, and I pass it like that to normalize and normalize returns some weird response.
What am I doing wrong?
The problem wasn't with vuejs, it was with the way I made the normalizr schemas. Because my response is an array at the root I should have had a new rooms array schema, like so:
const user = new schema.Entity('users');
const message = new schema.Entity('messages', {
user: user
});
const room = new schema.Entity('rooms', {
messages: [message]
});
const roomsSchema = [room];
And then use it like this: normalize(rooms, roomsSchema)

How to access local component variable from a callback in vue?

I am trying to set my components variable using an api rest command. I wanted to handle all responses through a function in its own file called handleResponse() which is below.
// api/tools/index.js
function handleResponse (promise, cb, cbError) {
var cbErrorRun = (cbError && typeof cb === "function")
promise.then(function (response) {
if (!response.error) {
cb(response)
}
else if (cbErrorRun) {
cbError(response)
}
}).catch(function (error) {
console.log(error)
if (cbErrorRun) {
var responseError = {
"status": 404,
"error": true,
"message": error.toString()
}
cbError(responseError)
}
})
}
export {handleResponse}
In my component file I have this
.... More above....
<script>
import { fetchStock } from '#/api/stock'
export default {
data () {
return {
stock: {},
tabs: [
{
title: 'Info',
id: 'info'
},
{
title: 'Listings',
id: 'listings'
},
{
title: 'Company',
id: 'company'
}
],
}
},
validate ({params}) {
return /^\d+$/.test(params.id)
},
created: function() {
var params = {'id': this.$route.params.stockId}
//this.$route.params.stockId}
fetchStock(
params,
function(response) { //on successful data retrieval
this.stock = response.data.payload // payload = {'name': test123}
console.log(response)
},
function(responseError) { //on error
console.log(responseError)
}
)
}
}
</script>
The current code gives me this error: "Uncaught (in promise) TypeError: Cannot set property 'stock' of undefinedAc". I think this happens because I no longer have access to 'this' within the callback I pass in the fetchStock function. How would I fix this without changing the current handleResponse layout.
You can try this trick
created: function() {
var params = {'id': this.$route.params.stockId}
//this.$route.params.stockId}
var self = this;
fetchStock(
params,
function(response) { //on successful data retrieval
self.stock = response.data.payload // payload = {'name': test123}
console.log(response)
},
function(responseError) { //on error
console.log(responseError)
}
)
}
You can either use an arrow function for you callback since arrow functions maintain and use the this of their containing scope:
created: function() {
var params = {'id': this.$route.params.stockId}
//this.$route.params.stockId}
fetchStock(
params,
(response) => { //on successful data retrieval
self.stock = response.data.payload // payload = {'name': test123}
console.log(response)
},
(responseError) => { //on error
console.log(responseError)
}
)
}
Or you can assign const vm = this n the beginning of your method before the callbacks like so.
vm stands for "View Model"
created: function() {
var params = {'id': this.$route.params.stockId}
//this.$route.params.stockId}
const vm = this;
fetchStock(
params,
function(response) { //on successful data retrieval
self.stock = response.data.payload // payload = {'name': test123}
console.log(response)
},
function(responseError) { //on error
console.log(responseError)
}
)
}
I advise using the const as opposed to var in the vm declaration to make it obvious the value of vm is a constant.

Vee-validate (VueJS) - evaluating a condition asynchronously

Can I make a custom validation rule that returns true/false based on a AJAX request? the problem is that the validate call has finished running when the AJAX call completes.
Do I need to have the rule set/unset a boolean variable based on which the field is valid/invalid?
const isValidNameRule = {
getMessage(field)
{
return "The name must be unique."
},
validate(validatingName)
{
var formData = new FormData();
formData.append("validatingName", validatingName);
this.$http.post("/api/isValid?name=" + validatingName, formData)
.then(function (response) {
// success
return true;
}, function (response) {
// error
return false;
});
}
};
Didn't know how to work with Promises.
Eventually got it working by extending one of the official samples:
const customRule = {
getMessage(field, params, data) {
return (data && data.message) || 'Something went wrong';
},
validate(aValue) {
return new Promise(resolve => {
var formData = new FormData();
formData.append("nameFilter", aValue);
$.ajax({
type: "POST",
url: url,
data: {
action: "validate",
value: aValue,
}
}).done(function (data) {
if (!ok)
{
resolve({
valid: false,
data: {message: "Condition not met"}
});
}
else
{
resolve({
valid: !! aValue,
data: undefined
});
}
});
});
}
};