figuredlimited / vue-mc Goto Github PK
View Code? Open in Web Editor NEWModels and Collections for Vue
Home Page: https://vuemc.io
License: MIT License
Models and Collections for Vue
Home Page: https://vuemc.io
License: MIT License
There seems to be a dependency on the underscore symbol, which not only requires lodash installed (as mentioned in dependencies), but also installed globally (which is typically not acceptable).
Source location: (
vue-mc/src/Structures/Model.js
Line 9 in d5e15e4
Hello,
Thanks, time & supports to create & maintain vue-mc. The custom attribute of a collection will not append to fetch request, please correct if I am wrong. Because of this.
https://github.com/FiguredLimited/vue-mc/blob/master/src/Structures/Collection.js#L626
I recommand to use default axios instance instead of axios global requester.
If we set others headers, they are add to all axios requests. Not only collection or model requests
REST standard calls for PUT when updating, why is POST the default?
On my model my fields are"
// I have all these types imported
// All the other validation rules seem to work asides from required
validation() {
return {
attribute1: integer.and(gte(1)).and(required),
attribute2: dateformat('YYYY-MM-DD').and(required),
attribute3: number.and(required),
attribute4: number.and(required),
}
}
I have a collection that holds these models, when I save the collection model objects that don't have all the required fields pass validation and get sent in my payload to the back end.
Example:
This object below will pass validation even through attribute4 is marks as required in the model:
let obj = new MyModel({
attribute1: 32123,
attribute2: '2018-07-09',
attribute3: 23452345,
})
I have tried explicitly defining options to force validation (even through the default for validateOnSave
is true
and I still can figure out how to force my validation rules.
This seems to only happen will the required
constraint, when saving collections bad formats are always caught.
Because not all locales are supported yet, I suggest documenting a list of supported locales so that one does not have to look into the source code for locale.js to see what locales are currently supported.
Hello,
This lib. is much useful particularly for me to built frontend in Vue & backend powered by Laravel. I was having to question/suggestions if it is not already included.
It's possible to extend axios params on fetch() method ? Like that :
const config = {
// axios specific config
};
collection.fetch(config);
The use case is really simple. In many parts on development app, we can use same collection or model Classes but fetch differents parameters (like with a filter query, specific orders, ...). And it's mote simple to use fetch params instead of extend collection/model methods.
Hello, thanks for you project!
Im get one error, but not understand why.
Model:
defaults(){
return {
places:new PlacesCollection(),
}
}
Component:
MyModel.places.add();
Collection is not valid
Why its happen?
Im not understand in documentation, how can I fetch data by collection class with queries?
var offers = new OffersCollection();
offers.page(1).fetch(() => {}); //Request with page sent, models in collection exist.
But how I can add dynamic parameters, for example: "...¶m1=123¶m2=321"?
My setup is roughly:
import { Trips } from "models";
export default {
data: () => ( {
date: "2018-06-15",
trips: new Trips()
} ),
async created() {
await this.trips.fetch();
},
computed: {
selectedDateTrips() {
return this.trips.filter( trip => trip.deliveryDate === this.date);
},
numCompletedTrips() {
return this.selectedDateTrips.filter( trip => trip.status === "Completed" ).length;
},
numScheduledTrips() {
return this.selectedDateTrips.filter( trip => trip.status !== "Completed" ).length;
}
},
render() {
return <p>{this.numCompletedTrips} completed trips, {this.numScheduledTrips} scheduled trips</p>;
}
};
This gives the Vue error:
"[Vue warn]: You may have an infinite update loop in a component render function."
This seems to happen whenever I'm doing two layers of filtering on an initial collection (this.trips -> this.selectedDateTrips -> completed/scheduled trip count).
This example may seem a little contrived (why don't I pass date to my api call?), but my actual setup is a bit more complicated, but essentially boils down to this.
Is there a way to avoid this?
Hi there! Playing around with VueMC to see if it's a good fit for the project I'm working on. I'm working with a server who's responses are of the following format:
// GET /api/widgets
{
"page": 0,
"per_page": 10,
"items": [
{
"_id": "5a01fea69d8a3a4ce8a70bbd",
"label": "FOO"
},
{
"_id": "5a01feab9d8a3a4ce8a70bbe",
"label": "BAR"
}
]
}
Using Collection.fetch()
, I've been seeing the following error thrown:
"Expected an array of models in fetch response"
I went ahead and overwrote the getModelsFromResponse
method in my Collection class definition, but I had to do a bit of digging to get there:
getModelsFromResponse (response) {
let models = response.getData().items
...
}
Is this the preferred approach with VueMC? With Backbone.js one typically defines a parse
method on Models or Collections to handle variations in response form - I want to ensure that the overwriting the getModelsFromResponse
method is the VueJS analogue to this approach. If so, I think it would be a valuable addition to the documentation and I would be happy to help with that endeavor :)
Also - as a side note - if this.isPaginated()
does return true, it would be nice if the user could specify an alternative to the data
field without overwriting the entire method:
// We're making an assumption here that paginated models are returned
// within the "data" field of the response.
if (this.isPaginated()) {
return _.get(models, 'data', models)
}
I want define accessor with model object like Laravel eloquent accessor.
https://laravel.com/docs/5.6/eloquent-mutators#accessors-and-mutators
Is it possbile?
export default class Person extends Model {
defaults() {
return {
id: null,
firstName: '',
lastName: ''
};
}
get fullname() {
return `${this.lastName} ${this.firstName} `;
}
}
const person = new Person({firstName: 'Shu', lastName: 'Ogawa'});
console.log(person.fullname); // Ogawa Shu
Hi,
I've got this list of items that I want to be displayed in a certain sort order. I thought I'd use it in a template like:
<item v-for="item in itemList.models.sort('field')"></item>
but since sort() doesn't return anything this doesn't work
I've 'solved' this by sorting anytime an item is added or when an item has changed. This way it's not possible to display the list twice in different sort orders.
Any suggestions?
It would be quite helpful with an overview of changes between versions that is more detailed than the release and less than the commit overview.
Whether it's kept in the readme, the documentation, the release overview, or somewhere else is a matter of taste, but I think it should be kept and might as weel be kept public ;)
I'm trying to use vue-mc (which is awesome, by the way) and have run into an issue:
The API I'm working with is responding with a data
and an optional meta
field for every request. As far as I read from the docs, vue-mc is expecting the actual data to be in the root node of the response data instead of in a separate data
field, as in this example. The meta
field includes additional cursor data, that I can handle myself.
{
"data": [
{
"id": "9788dd4e-d38b-4982-b1b5-41b1eb4d5a04",
"foo": "bar",
"bar": "baz"
},
{
"id": "e1d26b1f-8085-4e4f-af49-44ca039c65b1",
"foo": "bar",
"bar": "baz"
}
],
"meta": {
"current": "b5c30e88-f43e-421b-95ef-f45b891bf1c1",
"next": "7d46c5f1-709d-4945-995e-a141c085ae21"
}
}
How would I manage to make vue-mc get the data from the data
field? In another issue I saw that I can override the Collections getModelsFromResponse()
method. This works only for collections though.
Much easier would be to override Response.getData()
globally, but I have no idea how this could be done.
Are you planning to add support for attributes that are models?
I'm not sure if the use case is general enough, but I was looking for the following:
This might be along the lines of the feature you mention in Issue #39.
Hello,
There is a demo app? Would be very interesting!
Congratulations for the project.
While creating a new RegExp object with defined flags from previous regular expression, the following code won't work on IE:
new RegExp(/(ab|bc)/, 'g');
Possible solution is to seek for source
property on previous object and pass it as the first argument:
var a = /(ab|bc)/;
new RegExp(a instanceof RegExp ? a.source : a, 'g');
This issue appears on Structures/Base.js
=> getRouteReplacements
method.
The following method replacement might do the work:
getRouteReplacements(route, parameters = {}) {
const replace = {};
let pattern = this.getRouteParameterPattern();
pattern = new RegExp(pattern instanceof RegExp ? pattern.source : pattern, 'g');
for (let parameter; (parameter = pattern.exec(route)) !== null; ) {
replace[parameter[0]] = parameters[parameter[1]];
}
return replace;
}
this is my json response:
code: 200
data:[{id: 1, cif: "B12312312", razon_social: "Formacion Futuro S.L", email: "[email protected]",…}]
message: null
status:true
I can´t get my response. What is the proble?
I was seeing strange issues where many methods on the Model
class were not working correctly. As minimal example:
class Test extends Model {
defaults() {
return { length: 0 };
}
validation() {
return { length: positive };
}
}
test = new Test();
// test.attributes is an empty object
// test.validate() is true
Looking into it more, I found that lodash iterators use the presence of the length
attribute to determine if an object is an array or not. This causes all objects passed into lodash to be treated as an array.
I image I could override the rest calls to rename these properties coming from the server, but I'm wondering if there is an officially sanctioned way of dealing with reserved names, or if this is a problem that has not been considered.
It would be nice to add functionality to implement sorting on the server, something like that:
model.page(1).sorting({ name: 'desc' }).fetch() => ?page=1&sort=name&order=desc
or set all query params
model.queryParams({ page: 1, sort: 'name', order: 'desc' }).fetch() => ?page=1&sort=name&order=desc
it would be convenient to use with route
{ params: this.$route.query }
Hi, I have a problem with vue-mc :
I try to remove an item on unexist route (I test my interface first). But, if the model.delete()
failed, the deleting
is already set to true and I can't retry without refresh my entire collection.
In a normal way, after the request, if it was an error, we can retry the delete. It's possible to fix that ?
Thanks
When define my model like this
defaults () {
return {
'keys': []
}
}
mutations () {
return {
'keys': Array
}
}
and response contains
{keys: [1,2,3]}
model contains next data
_attributes.keys === [[1,2,3]]
http://vuemc.io/#model-request-custom
It's still not clear how to write a custom method, I'm still trying to figure out which method do I need to call to save API's response to model.
As far as I can tell, it's currently impossible to have async validation rules.
Common scenario: You need to check if an email address is available or already taken when a user is changing their email address.
I'm migrating some validation from VeeValidate to models, and how they handle it is letting rules return a promise that resolves { valid: Boolean }
. Docs Reference and Code Reference
I have a model that have a collection as one of properties and i cant add new models
in that collection. It throw the error 'Error: Collection is not valid'. I find out that error is
happen because field _uid that defined in Base class is disappear on nested collection
because lodash deepClone doesn get it.
Or maybe there is another way to create a model with array of another model in the property?
From documentation:
// Set the on the global on the window so that you don't have to import
// the base classes in every model and collection class or component.
window.Model = Model;
window.Collection = Collection;
This is really bad practice. It leads to maintainable code, and all kinds of conflicts. No-one should ever do that, and documentation should certainly not recommend it.
Importing these symbols is a single line, which has two purposes:
Purpose no1 can be circumvented by using a global import, but purpose no2 is still really relevant, and should not be left out.
I'm using a backend that returns {result: 'ok'} when an update was succesful.
However :
item.onSaveSuccess() calls
this.update({result:'ok'} which in turn calls
this.assign({result:ok}) which calls
this.set(defaultsDeep({}, {result:ok}, cloneDeep(this.defaults())));
and presto: item is set to all defaults
I wonder how calling this.update() doesn't preserve the original content?
the comment in Model.update is:
// A plain object implies that we want to update the model data.
// It's not a requirement to respond with a complete dataset,
// eg. a response to a patch request might return partial data.
which is entirely true, but that's not what's happening.
Is there any simple way to upload a File
Object via vue-mc?
Do you plan to add TypeScript definition file?
Can you please explain why to prefer vue-mc over vuex?
Related to #9 (comment).
I've run into some errors where my User model has a MembershipList collection similar to below
{
"name": "Test",
"email": "[email protected]",
"memberships": [
{
"id": 1
}
]
}
When I try to cast "memberships"
to MembershipList, it seems to throw a tonne of Errors. Haven't looked too much into it, but from the outside it looked like a recursion error.
// Attribute mutations.
mutations () {
return {
memberships: (memberships) => {
return new MembershipList(memberships)
}
}
}
so using the following seemed to solve it.
// Attribute mutations.
mutations () {
return {
memberships: (memberships) => {
if (typeof memberships.models === 'undefined') {
return new MembershipList(memberships)
}
return memberships
}
}
}
Seems like an easy fix to this is to just test to see if the collection is accepting an array or if it's accepting another one of itself.
Just a quick request to see if @rtheunissen is happy with me fixing this like that & I'll submit a PR.
Is there a reason why Collection.clearState()
sets loading to true, while Model.clearState()
sets loading to false? Don't know if it's a bug or just some logic I'm not understanding.
I'm surprised to see this library has no methods toArray
and toObject
on Collections and models to use this on non-compatibles vueJS components.
It's possible to add this vital functions ?
Thanks
I want to make a response keys mapping before requests are made and before response is assigned to model. Is this possible without overriding methods like onFetchSuccess()?
One thing that could work would having different mutators for responses and requests.
Attribute errors are currently always an array, but in many cases you only want to show one. This results in a lot of [0]
accesses, which can be avoided with an option like onlyUseFirstError
or forceSingleError
.
I have an issue with all the getters being hit, even before the data is loaded, which gives a bunch of nasty undefined.
I have created this to show the issue:
https://runkit.com/sarke/5a5e956c9fbc9a0012585e0f
Getters should only be called when directly accessed.
Moment.js is a fairly large dependency, especially if this is the only package you have that's using it. It'd be nice if date-fns was used instead, or simply supplying a way to use non-date related validation rules without Moment being imported, then we can redefine our own date-related rules using whatever date library.
See #15
At the moment the support for nested structures is limited. We'd like to improve this as it's a common situation and should in theory work as you would expect. This issue is a place to collect all the things we'd like to achieve when we get to improving this support.
parent.saved('child.attr')
and parent.child.saved('attr')
I am using vue cli with webpack-simple. I am getting this error.I have install all dependencies of vue-mc. You can see my devDepencies:
"devDependencies": {
"axios": "^0.17.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"file-loader": "^1.1.4",
"lodash": "^4.17.4",
"moment": "^2.19.1",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"underscore": "^1.8.3",
"vue-loader": "^13.0.5",
"vue-mc": "^0.1.1",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.1"
}
But I am getting this error.
vue-mc.es.js?c9ea:2456
Uncaught ReferenceError: _ is not defined
at eval (vue-mc.es.js?c9ea:2456)
at Object.<anonymous> (build.js:1010)
at __webpack_require__ (build.js:679)
at fn (build.js:89)
at eval (31:4)
at Object.<anonymous> (build.js:934)
at __webpack_require__ (build.js:679)
at fn (build.js:89)
at Object.<anonymous> (build.js:789)
at __webpack_require__ (build.js:679)
I'm able to use this with any rest service that uses laravel pattern for endpoints? I have a restful springboot application and i would like to use together that, If I apply laravel pattern for the endpoints is it supposed to work fine or is there any limitation?
I need to set defaults for axios like "withCredentials" property, baseUrl, headers, etc (and also interceptos). I tried to set it to axios.defaults on app.js but it didn't work. How can I achieve this?
Im trying overwrite getters&setters for simple relations support, but get error can't redefine non-configurable property
. Can you add please configurable: true, in registerAttribute for Object.defineProperty?
is it possible to make it work with graphql ?
eg apollo client
Hello, I have a problem with vue-mc and Babel.
If I update babel in last versions (7.0.0 beta 48 and more) I have this error on my project if I ass custom method on your Collection class :
Input Code
class MyClass extends Collection {
setPageSize(pageSize) {
this._pageSize = pageSize;
}
}
const obj = new MyClass();
obj.setPageSize(12); // TypeError: obj.setPageSize is not a function
Babel Configuration (.babelrc, package.json, cli command)
{
"plugins": [
"lodash"
],
"presets": [
"poi",
["@babel/env", {
"targets": {
"browsers": [
">0.25%",
"not ie 10",
"not op_mini all"
]
}
}]
]
}
Environment
loader
I've create same issue on Babel repo : babel/babel#8063
Would it be possible to get some more basic examples in the documentation. There isn't any examples of fetching from an api, only creating from a hard coded array.
Perhaps it's too simple a question but i've been really struggling. Right now this is the only thing I can get working to get an instance of a model from an API, but i'm sure it can't possibly be right as it seems far too convoluted.
// Task.vue
// The template would be displaying details about a single Task
export default {
props: {
taskId: {
type: Number,
default: 1
},
},
created () {
new Task({id: this.taskId}).fetch().then(response => {
this.task = new Task(response.response.data);
}).catch((error) => {
console.log(error);
});
},
data: function() {
return {
task: null
};
},
};
// Json Response:
{"id":1,"title":"Task 1","description":"A description"},
All i'm trying to do is get a single instance of a Task, in Laravel it would look something like this:
$task = Task::find(1);
$task->doSomething();
echo $task->title;
// etc
How would you get a single instance of a Task with the id of 1 using vue-mc?
The documentation shows:
// Create a new task with initial attributes.
let task = new Task({title: 'Task 1'});
console.log(task.doSomething());
console.log(task.title);
But obviously that's not using fetch or getting data from a database?
Sorry for what is probably a very stupid and simple question but it's really not at all clear and hours of googling has got me nowhere. I've read every single issue hoping someone would at least have posted an example when having another issue, but there's nothing. It would be great if the docs had more examples of things like this even if it seems obvious to some people.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.