I have a JSON object like this in my application:
var pages = {
home: {
title: "Home",
description: "The home page",
file: "home.html",
url: "/home"
},
blog: {
title: "Blog",
description: "Our blog",
file: "blog.html",
url: "/blog"
}
};
The properties file and url can always be derived from the respective key, so I currently define the above object like this in my code:
var pages = {
home: {
title: "Home",
description: "The home page"
},
blog: {
title: "Blog",
description: "Our blog"
}
};
$.each(pages, function(key, value) {
value.file = key + ".html";
value.url = "/" + key;
}
However, since file and url are derived attributes, adding them to the object seems redundant. But since I pass the value around for each page, not the key, I would have to add it to the object as well, which would also be redundant. Like this:
var pages = {
home: {
title: "Home",
description: "The home page"
},
blog: {
title: "Blog",
description: "Our blog"
}
};
$.each(pages, function(key, value) {
value.jsonKey = key;
}
Now I have three different approaches and don't really like any of those. I think this should be a fairly common problem, so how would you approach this? And what if the derived attribute is to be used more than once?
you should consider storing pages as a list of objects rather than as an object with properties. This seems more consistent logically and solves your redundancy concerns.
var pages = [
{
key: 'home'
title: "Home",
description: "The home page",
},
{
key: 'blog',
title: "Blog",
description: "Our blog",
}
];
additionally. you can create classes for page objects and use methods that compute the derived properties (optionally caching them, in case you think repeated access is costly. However, doing that for simple string concatenation seems like an overkill)
Why do you want to store the same data in a different form, when you already have it in one form(your key).
In my opinion, don't go for any of these, because whenever you wish to get the file and url for a particular page, you can easily get it from the page.key.
Related
I'm making an admin dashboard and I need to ask for data (for example when creating or updating data) a lot. I am already using vue-sweetalert2 which made me aware of how easy it is to use this.$swal.fire().then()...
I was wondering, how would I go about making my own kind of thing like that (without using TypeScript)?
let reply = await this.$ask(fields)
alert("You entered: " + reply.yourname.answer)
Then in the component that I load in on every page, I would have a modal which takes the fields and allows for user input. When a user clicked submit or exited the modal, it needs to return a / the value(s).
I'm thinking of using it this way:
// Ask for new team name & description
let modalResult = await this.$ask({
fields: [
{
title: "Team name",
placeholder: "Give youre team a name!",
key: "teamName",
type: "text"
}, {
title: "Team description",
placeholder: "What's your team about?",
key: "teamDescription",
type: "text"
}
],
modal: {
variant: "primary",
icon: null,
title: "Make a new team",
confirmButtonText: "Create team",
cancelButtonText: "Cancel"
}
});
console.log("Team name: " + modalResult.data.teamName);
console.log("Team description: " + modalResult.data.teamDescription);
However, I honestly have no idea how I'd go about making this possible. What I've thought of:
Mixins: Of what I've learnt so far, I don't know how to put a template file in it. (so a .vue file, only a .js file).
Here's a screenshot of :
what I'm trying to say
Thanks in advance! :-)
When you're setting up your vue instance (usually in main.js), you can put your method on as a prototype
Vue.prototype.$ask= (your function or your object);
Here's some vuejs docs on the subject
https://v2.vuejs.org/v2/cookbook/adding-instance-properties.html
I'm new to vue.js and I'm trying to use vuex. Here is my issue:
I have a list of articles (which is a component) linked with a store with v-for="article in articles and a computed property:
computed: {
articles() {
return this.$store.state.articles
}
}
So here is the data in my store:
state: {
articles: [{
title: "Article 1",
id: 1,
description: "Article 1",
}, {
title: "Article 2",
id: 2,
description: "Article 2",
}
}]
}
When I click on an article, I want it to redirect to the article page template (which is a component) with <router-link :to="{path: '/article/'+article.id}"></router-link>.
What I'm trying to do is bind the data of the correct article in the articlePage template.
The issue is that if I apply the same computed property to my articlePage.vue component with a v-for, I will display all of the article on the same page. I would like to display only the matching id component.
How can I do that?
Thank you for your time :)
From your comments I understand that you use vue-router module
So in your routes.js (or structure ) your must have something like this
const router = new VueRouter({
routes: [
{ path: '/articles', component: articlesPage },
{ path: '/article/:id', component: articlePage }
]
})
Then in your articlePage component you can extract ":id" like this:
this.$route.params.id
because vue-router gives you access to the object $route with methods and properties
Check more here https://router.vuejs.org/guide/essentials/dynamic-matching.html
then you can use it to search the articles array and find the data and present them
e.x.
computed:{
selectedArticle(){
var article_id = this.$route.params.id;
var articles = this.$store.state.articles;
var article = null;
for(var a=0;a<articles.length;a++){
if(articles[a].id == article_id ){
article = articles[a];
break;
}
}
return article;
}
}
For the application I am currently building, there is a dataset of links associated with certain customer profiles and the user receives a list, which looks like the following:
function getList(customItems){
var messageData = {
recipient: {
id: recipientId
},
message: {
attachment: {
type: "template",
payload: {
template_type: "generic",
elements: []
}
}
}
};
customItems.forEach(function(item) {
var url = item._id;
var listItem = {
title: item.title,
subtitle: "",
item_url: url,
image_url: "http://random.image.com",
buttons: [{
type: "postback",
title: "Get other items",
payload: "TEST",
}]
};
messageData.message.attachment.payload.elements.push(listItem);
Anyway, I would like to generate some image from given url the same way it appears in messenger if the link is pasted directly into the text box and haven't figured out yet how to do it. Also, by the way, if I try to display some random image for testing purpposes (http://random.image.com replaced by some valid image url), the image doesn't appear.
Does anyone know how to generate images to be displayed for given urls dynamically?
You either have to implement your own (or open source) thumbnail image processor (with something like ImageMagick, GraphicsMagick, G'MIC, gd, PhantomJS + HTML5 Canvas), or use a SaaS solution like imgix.com
I am currently playing around with a bunch of new technology of Facebook.
I have a little problem with GraphQL schemas.
I have this model of an object:
{
id: '1',
participants: ['A', 'B'],
messages: [
{
content: 'Hi there',
sender: 'A'
},
{
content: 'Hey! How are you doing?',
sender: 'B'
},
{
content: 'Pretty good and you?',
sender: 'A'
},
];
}
Now I want to create a GraphQL model for this. I did this:
var theadType = new GraphQLObjectType({
name: 'Thread',
description: 'A Thread',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLString),
description: 'id of the thread'
},
participants: {
type: new GraphQLList(GraphQLString),
description: 'Participants of thread'
},
messages: {
type: new GraphQLList(),
description: 'Messages in thread'
}
})
});
I know there are more elegant ways to structure the data in the first place. But for the sake of experimenting, I wanted to try it like this.
Everything works fine, besides my messages array, since I do not specify the Array type. I have to specify what kind of data goes into that array. But since it is an custom object, I don't know what to pass into the GraphQLList().
Any idea how to resolve this besides creating an own type for messages?
You can define your own custom messageType the same way you defined theadType, and then you do new GraphQLList(messageType) to specify the type of your list of messages.
I don't think you can do this in GraphQL. Think that it's a bit against GraphQL philosophy of asking for the fields "you need" in each component against asking for "them all".
When the app scales, your approach will provoque higher loads of data. I know that for the purpose of testing the library looks a bit too much but it seems this is how it is designed. Types allowed in current GraphQL library (0.2.6) are:
GraphQLSchema
GraphQLScalarType
GraphQLObjectType
GraphQLInterfaceType
GraphQLUnionType
GraphQLEnumType
GraphQLInputObjectType
GraphQLList
GraphQLNonNull
GraphQLInt
GraphQLFloat
GraphQLString
GraphQLBoolean
GraphQLID
I have an API that returns JSON that is not properly formatted for Ember's consumption.
Instead of this (what ember is expecting):
{ events: [
{ id: 1, title: "Event 1", description: "Learn Ember" },
{ id: 2, title: "Event 2", description: "Learn Ember 2" }
]}
I get:
{ events: [
{ event: { id: 1, "Event 1", description: "Learn Ember" }},
{ event: { id: 2, "Event 2", description: "Learn Ember 2" }}
]}
So if I understood correctly, I need to create a custom Serializer to modify the JSON.
var store = DS.Store.create({
adapter: DS.RESTAdapter.create({
serializer: DS.Serializer.create({
// which hook should I override??
})
})
});
I've read the code comment related to the DS.Serializer, but I can't understand how to achieve what I want...
How can I do it?
ps: My goal is to make App.Event.find() work. Currently, I get Uncaught Error: assertion failed: Your server returned a hash with the key 0 but you have no mapping for it. That's why I need to fix the JSON received.
edit: Here's how I made it work, for now:
extractMany: function(loader, json, type, records) {
var root = this.rootForType(type),
roots = this.pluralize(root);
json = reformatJSON(root, roots, json);
this._super(loader, json, type, records);
}
I am assuming that the responses contain the IDs only, and that you are trying to extract them.
You will want to subclass DS.JSONSerializer, which supplies the basic behavior for dealing with JSON payloads. In particular, you will want to override the extractHasMany hook:
// elsewhere in your file
function singularize(key) {
// remove the trailing `s`. You might want to store a hash of
// plural->singular if you deal with names that don't follow
// this pattern
return key.substr(0, key.length - 1);
}
DS.JSONSerializer.extend({
extractHasMany: function(type, hash, key) {
return hash[key][singularize(key)].id;
}
})