I have a Base Vue Component, which handles items. Now i've extended that component with a CompanyItem and a EducationItem. But when i load both the directives, it will call a GET method 4 times. Also: i have a click handler on 2 models (example: openUpdateOrCreateModal()) which is loaded in one of the directives. When i click, the other directive is triggered too. Anyone a idea?
Base
module.exports = {
props: ['user', 'update_url', 'store_url', 'delete_url', 'show_url', 'index_url', 'item_type'],
mounted() {
Bus.$emit('index');
},
data(){
return {
form: {},
items: [],
mainItem: {},
item: {},
}
},
created(){
},
methods: {
resetForm(){
this.form = new SparkForm({
general: {
title: null,
},
item: this.getItemProperties(),
address: {
address_line_1: null,
address_line_2: null,
city: null,
province: null,
zip_code: null
}
});
this.mainItem = null;
},
getItemProperties(){
return {};
},
showModal(){
$('#create-update-'+this.item_type+'-modal').modal('show');
},
hideModal(){
$('#create-update-'+this.item_type+'-modal').modal('hide');
},
/**
* Gets a list with specific items
*/
index(){
console.log('Call index');
axios.get(this.index_url)
.then(response =>
{
this.items = response.data.data;
});
},
}
};
Education
var base = require('./cv-item-base');
Vue.component('cv-educations-management', {
mixins: [base],
methods: {
getItemProperties(){
return {
start_at: null,
end_at: null,
description: null,
finished_education: null,
level: null,
}
}
}
});
Companies
var base = require('./cv-item-base');
Vue.component('cv-company-list', {
mixins: [base],
methods: {
getItemProperties(){
return {
start_at: null,
end_at: null,
position: null,
description: null,
phone_number: null,
branch: null,
referral: null,
}
}
}
});
HTML
<cv-company-management :user="user"
:update_url="'{{route('application.manage.companies.update')}}'"
:show_url="'{{route('application.manage.companies.show')}}'"
:delete_url="'{{route('application.manage.companies.destroy')}}'"
:store_url="'{{route('application.manage.companies.store')}}'"
:index_url="'{{route('application.manage.companies.index')}}'"
:item_type="'company'"
inline-template>
</cv-company-management>
<cv-education-management :user="user"
:update_url="'{{route('application.manage.educations.update')}}'"
:show_url="'{{route('application.manage.educations.show')}}'"
:delete_url="'{{route('application.manage.educations.destroy')}}'"
:store_url="'{{route('application.manage.educations.store')}}'"
:index_url="'{{route('application.manage.educations.index')}}'"
:item_type="'education'"
inline-template>
</cv-education-management>
Related
I'm trying to make the code below work knowing that computed properties can't take parameters. Do you have any idea ? I'm exploring the use of watchers on functions but I was wondering if there was not an easier solution to do this.
var app = new Vue({
el: '#app',
data() {
return {
sessions: {
"156": {
tickets: {
"01": {
available: true,
},
"02": {
available: false,
},
}
},
},
tickets: {
"01": {
attr: "somestring",
},
"02": {
attr: "someotherstring",
},
},
},
};
},
computed: {
sessionTickets(session) {
let _this = this;
let sessionTickets = {};
$.each(_this.session.tickets, function(ticketId, sessionTicket) {
if(sessionTicket.available) {
sessionTickets[ticketId] = _this.tickets[ticketId];
}
});
return sessionTickets;
},
},
});
<div v-for="session in sessions">
<div v-for="sessionTicket in sessionTickets(session)">
{{ sessionTicket.attr }}
</div>
</div>
Thanks to "WallOp" for making me realize that my computed property is in a sessions loop and so it can normally become a class method and be refreshed on sessions refresh !
I think you can use computed property. Just filter tickets of sessions. Like this:
var app = new Vue({
el: '#app',
data() {
return {
sessions: {
"156": {
tickets: {
"01": {
available: true,
},
"02": {
available: false,
},
}
},
},
tickets: {
"01": {
attr: "somestring",
},
"02": {
attr: "someotherstring",
},
},
},
};
computed: {
filteredSessions() {
return this.sessions.map( session => {
let tickets = {};
for(key in session.tickets) {
if(session.tickets[key].available && this.tickets.hasOwnProperty(key)) {
tickets[key] = this.tickets[key];
}
}
session.tickets = tickets;
return session;
});
},
},
});
<div v-for="session in filteredSessions">
<div v-for="ticket in session.tickets">
{{ ticket.attr }}
</div>
</div>
I have data from API but I cannot set data in an array to this.data in vue.js
This is data(JSON) from API
Can you tell me about syntax of this
{"id":1613,
"name_org":"US company",
"picture":"default.jpg",
"headerpic":"no-preview.png",
"description":null,
"address":null,
"type":"hardware,software,network",
"rating":0,
"created_at":"2019-03-27 18:50:51",
"updated_at":"2019-03-27 18:50:51",
"review":[{
"review_id":3,
"org_id":1613,
"user_id":2,
"description":"Very good",
"rating":3,
"created_at":null,
"updated_at":null},
{"review_id":4,
"org_id":1613,
"user_id":1,
"description":"Not bad",
"rating":5,
"created_at":null,
"updated_at":null}]
}
I have a problem in the review because it is an array.
I cannot set data from API to data in vue
<div v-for="review in reviews" class="box">{{review.review_id}}</div>
<script>
export default {
props: ["id"],
data() {
return {
name_org: "",
picture: "",
headerpic: "",
description: "",
reviews: [],
review: {
review_id: "",
org_id: "",
user_id: "",
description: ""
}
};
},
mounted() {
axios.get("/api/listorgs/" + this.id).then(response => {
var listorg = response.data;
this.name_org = listorg.name_org;
this.picture = listorg.picture;
this.description = listorg.description;
this.headerpic = listorg.headerpic;
});
},
};
</script>
As your API response is an object, define an empty object under data.
data() {
return {
orgsData: {}
}
}
Then use it with your API such as below:
this.orgsData = response.data
And append it in your HTML
<div v-for="review in orgsData.reviews" class="box">{{review.review_id}}</div>
Hope it helps!
Hi this is my code,
var vm = new Vue({
el: '#el',
data: {
input: {
sorting: "",
brand: null,
model: null,
country: "all",
cap: "",
radius: ""
}
},
watch: {
input: {
handler(newInput) {
},
deep: true
}
}
});
Here I'm watching weather input object changes. But I need to watch only some items only input object. For example I need to do something if input.country changes but not when input.brand changes. Unfortunately my code is complex and can't take items out of input object.
Just watch what you need:
watch: {
'input.country': {
handler(newCountry) {
}
}
}
Declare a computed value who target this.item.country:
computed: {
itemCountry() {
return this.item.country;
}
}
And watch this new computed value:
watch: {
itemCountry: {
immediate: true,
handler(newInput) {
// do your stuff
}
}
}
I have this jSON structure.
{
"customer": {
"idcustomer": 2,
"name": "test_2",
"vat": "test_vat_2",
"obs": "obs_2",
"deleted": 0
},
"addresses": [
{
"idaddress": 9,
"street": "street_2_9",
"number": "number_2_9",
"country": "country_2_9",
"default": true,
"label": "labe_2_9",
"deleted": 0
},
{
"idaddress": 10,
"street": "1",
"number": "number_2_9",
"country": "country_2_10",
"default": false,
"label": "label_2_10",
"deleted": 0
}
],
"contacts": []
}
With knockout mapping plugin I am able to generate a knockout observable object. However, when trying to add extra properties to the object using the mapping parameter I find some issues. The goal is to add "SelectedAddress" to the main object and in each address a "defaultLabel" observabale.
Currently i have this mapping structure to add the property to the address children:
var mapping = {
'addresses': {
create: function (options) {
return (new (function () {
this.defaultLabel= ko.computed(function () {
return (this.default() == 0) ? "" : this.label();
}, this);
ko.mapping.fromJS(options.data, {}, this);
})());
}
},
}
and this to add the "SelectedAddress" to the main JSON:
create: function (options) {
return new function () {
var model = ko.mapping.fromJS(options.data, {}, this);
// Direccion
model.direccionSeleccionada = ko.observable();
model.getDireccion = ko.computed({
read: function() {
if (model.direccionSeleccionada() != null) {
return model.direccionSeleccionada();
} else {
return [{
idaddress: -1,
street : '',
number: '',
country: '',
default: '',
label: '',
deleted: '',
}];
}
},
write: function(value) {
self.direccionSeleccionada(value);
},
owner: self
});
}
}
I can not find a way to have them both
Ideas?
Thank you
I figured it out. Just for someone; Just as simple as when generatint he mapping of "addresses", add inside another mapping for it.
var mapping = {
create: function (options) {
return new function () {
var model = ko.mapping.fromJS(options.data, {
'adresses': {
create: function (options) {
return (new(function () {
this.labelDefault= ko.computed(function () {
return (this.default() == 0) ? "" : this.label();
}, this);
ko.mapping.fromJS(options.data, {}, this);
})( /* call the ctor here */ ));
}
},
}, this);
model.direccionSeleccionada = ko.observable();
model.getDireccion = ko.computed({
read: function () {
if (model.selectedAddress() != null) {
return model.selectedAddress();
} else {
return [{
idaddress: -1,
street: '',
number: '',
country: '',
default: '',
label: '',
deleted: ''
}];
}
},
write: function (value) {
self.selectedAddress(value);
},
owner: self
});
}
}
}
Thank you!
I want to use mutation in Relay to change an array (not connection). The array is typed GraphQLList in the GraphQL side. The graphql side worked perfectly, but relay side needs dataID for each item in an array. And when I am inserting new item or modifying existing item in the array, there are no dataID provided? What is the right way to do this? By the way, I am using redux to maintain the list, and submit changes via relay at the end.
The schema:
let widgetType = new GraphQLInputObjectType({
name: 'Widget',
fields: () => ({
label: {
type: GraphQLString
},
type: {
type: GraphQLString
},
list: {
type: new GraphQLList(GraphQLString)
},
description: {
type: GraphQLString
},
required: {
type: GraphQLBoolean
}
})
});
let modifyFormMutation = mutationWithClientMutationId({
name: 'ModifyForm',
inputFields: {
id: {
type: new GraphQLNonNull(GraphQLString)
},
name: {
type: new GraphQLNonNull(GraphQLString)
},
userId: {
type: new GraphQLNonNull(GraphQLString)
},
widgets: {
type: new GraphQLList(widgetType)
}
},
outputFields: {
formEdge: {
type: formConnection.edgeType,
resolve: (obj) => {
return {
node: {
id: obj.id,
name: obj.name,
userId: obj.userId,
widgets: obj.widgets
},
cursor: obj.id
};
}
},
app: {
type: appType,
resolve: () => app
}
},
mutateAndGetPayload: ({
id, name, userId, widgets
}) => {
db.collection('forms').findOneAndUpdate({
_id: new ObjectID(id)
}, {
name, userId, widgets, createAt: Date.now()
});
return {
id, name, userId, widgets
};
}
})
Relay mutation:
export default class ModifyFormMutation extends Mutation {
getMutation () {
return Relay.QL`mutation{modifyForm}`;
}
getFatQuery() {
return Relay.QL`
fragment on ModifyFormPayload {
formEdge
app { forms }
}
`;
}
getCollisionKey() {
return `check_${this.props.app.id}`;
}
getConfigs() {
return [{
type: 'FIELDS_CHANGE',
fieldIDs: {
formEdge: {node: this.props.node},
app: this.props.app.id
}
}];
}
getVariables() {
return {
name: this.props.node.name,
id: this.props.node.id,
userId: this.props.node.userId,
widgets: this.props.node.widgets
};
}
getOptimisticResponse() {
return {
formEdge: {
name: this.props.node.name,
id: this.props.node.id,
userId: this.props.node.userId,
widgets: this.props.node.widgets
}
};
}
}
And error message from browser:
"Variable "$input_0" got invalid value
{"name":"asdfasdfsa","id":"57e790cec252f32aa805e38d","userId":"57e10a02da7e1116c0906e40","widgets":[{"dataID":"client:618507132","label":"sdfas","type":"text","list":[],"description":"","required":true},{"label":"sfasdfasaaa","list":[],"type":"number","description":"","required":"false"}],"clientMutationId":"0"}.↵In
field "widgets": In element #0: In field "dataID": Unknown field."