I'm trying to access provided / injected values from a mixin in VueJS. I can see those values from any component but not from the mixin. Is what I'm attempting possible?
https://jsfiddle.net/frang/c6c7kqhp/2/1
let myMixin = {
inject: ['myDependency'],
created: function() {
console.log('in mixin', this.myDependency)
}
}
Vue.component('my-component', {
inject: ['myDependency'],
created: function() {
console.log('in component', this.myDependency)
}
})
new Vue({
el: '#example',
provide() {
return {
myDependency: 'here is my value'
}
},
mixins: [myMixin]
})
The issue is that you are trying to inject the myDependency property in the same Vue instance that you are providing it.
Vue instances that specify a provide property give their child components access to that value via inject. But, you cannot inject the provided value on the same instance.
You need to use the mixin in a child component:
Vue.component('my-component', {
mixin: ['myMixin'],
created: function() {
console.log('in component', this.myDependency)
}
})
Here's a working fiddle.
Related
how do I decorate a custom method inside my CrudController so that the Swagger documentation would be shown as the one from getManyBase? Meaning I need to have all of the filter fields.
I tried this way
#Get('/projects')
#UseInterceptors(CrudRequestInterceptor)
#ApiResponse({ status: 200, type: Project, isArray: true })
getManyProjects(#ParsedRequest() req: CrudRequest, #Request() request)
: Promise<GetManyDefaultResponse<Project> | Project[]> {
const { id, role } = request.user;
if (role === UserRoles.User) {
req.parsed.filter.push({
field: 'userId',
operator: 'eq',
value: id,
});
}
return this.projectService.getMany(req);
}
but the Swagger docs shows empty for the query parameters,
while I'm expecting something like getManyBase.
Funny thing is, the method would work properly if I send the filter string, but I need Swagger to display them as well.
Advice?
See this area in the nestjsx/crud repo.
If you add something like this to your constructor that should do it:
import { Swagger } from '#nestjsx/crud/lib/crud';
...
constructor() {
const metadata = Swagger.getParams(this.getManyProjects);
const queryParamsMeta = Swagger.createQueryParamsMeta('getManyBase');
Swagger.setParams([...metadata, ...queryParamsMeta], this.getManyProjects);
}
In my version "#nestjsx/crud": "^5.0.0-alpha.3"
import { Swagger } from '#nestjsx/crud/lib/crud';
...
constructor() {
const metadata = Swagger.getParams(this.getManyProjects);
const queryParamsMeta = Swagger.createQueryParamsMeta('getManyBase',{
model: { type: MyModel },
query: {
softDelete: false,
},
});
Swagger.setParams([...metadata, ...queryParamsMeta], this.getManyProjects);
}
If the constructor approach does not work for you. Then probably your controller has scope: REQUEST. So controller instance is not created while application initialisation. In this case, you can have custom method inside a controller, like
initSwagger() {
const metadata = Swagger.getParams(this.getManyProjects);
const queryParamsMeta = Swagger.createQueryParamsMeta('getManyBase',{
model: { type: MyModel },
query: {
softDelete: false,
},
});
Swagger.setParams([...metadata, ...queryParamsMeta], this.getManyProjects);
}
then in your main entrypoint file you can write:
app.get(YourController).initSwagger();
It will do the trick
Playing with Relay I got problems with accessing data. I was trying to reproduce the issues with official Todo example of the Relay project. Please consider gist in order to change Todo example.
here
Here are the questions:
Why Summary component cant get access to sibling (viewer) component data?
What the reason for "queries must have exactly one field"? GraphQL doesn't have such limitations I believe.
Why I got Invariant Violation: Relay(TodoApp).getFragment(): summary is not a valid fragment name ?
Thanks in advance!
Whatever data Summary wants to use from viewer has to be delclared as GraphQL in the Summary container, and composed all the way down to the root of the application.
class Summary extends React.Component {
render() {
return <span>{this.props.viewer.bar}</span>;
}
}
export default Relay.createContainer(Summary, {
fragments: {
viewer: () => Relay.QL`
fragment on Viewer {
bar
}
`,
},
});
class TodoApp extends React.Component {
render() {
return <Summary viewer={this.props.viewer} />;
}
}
export default Relay.createContainer(TodoApp, {
fragments: {
viewer: () => Relay.QL`
fragment on Viewer {
foo
${Summary.getFragment('viewer')}
}
`,
},
});
Note that the foo field will not be available inside Summary. We mask it out since Summary didn't ask for it.
You can have multiple queries in a Relay.Route, but only one root field per query. We need this one-to-one correspondence so that we know which result to assign to which prop.
class MyRoute extends Relay.Route {
queries: {
summary: () => Relay.QL`query { summary }`,
viewer: () => Relay.QL`query { viewer }`,
},
/* ... */
}
You need to compose the summary fragment all the way down to the root of the application, making it available on TodoApp.
export default Relay.createContainer(TodoApp, {
fragments: {
summary: () => Relay.QL`
fragment on Summary {
${Summary.getFragment('summary')}
}
`,
},
});
I work in durandal project and use breeze entities.
In my project, I need to create client entity, and on the creating, give initialValues.
Normally, whant you want to give initialValues to new entity, you pass it to createEntity function.
For example:
dataContext.createEntity('employee', {age:40, city:'OurCity'});
So you get new empty instance of employee with default data for age and city.
I want to do it with entity type that contain complexFields.
But it doesn't work.
My entity is client-entity.
Here is the code:
addFormType(store);
function addFormType(store) {
store.addEntityType({
shortName: "FormDTO",
autoGeneratedKeyType: AutoGeneratedKeyType.Identity,
dataProperties: {
key: {//auto primary key. numeratorA and Code cannot be key, becose for new records thier aren't unique
dataType: DataType.Int32, isNullable: false, isPartOfKey: true
}
TaxYear: {
dataType: DataType.String, validators: [Validator.required({ message: 'דרוש' })]
},
Unit_A: {
name: "FormUnit_A",
complexTypeName: 'FormUnit_A:#'
}
}
});
store.registerEntityTypeCtor("FormDTO", null, FormInit);
}
function FormInit(entity) {
validationHelper.initializer(entity);
}
addFormUnit_AType(store);
function addFormUnit_AType(store) {
store.addEntityType({
shortName: "FormUnit_A",
isComplexType: true,
dataProperties: {
CompanyName: {
dataType: DataType.String
},
CompanyAddress: {
dataType: DataType.String
}
}
});
store.registerEntityTypeCtor("FormUnit_A", null, null);
}
I tried to initial it by the follwing rows:
var defaultData = {
TaxYear:0,
Unit_A:{
CompanyName:'ourCompany',
CompanyAddress:'Zar 200 OurCity'
}
};
clientManager.createEntity('FormDTO', defaultData);
But it throws exception: "Object doesn't support property or method 'getProperty'"
I tried also to pass an One-layer object with all of the properties:
var defaultData = {
TaxYear:0,
CompanyName:'ourCompany',
CompanyAddress:'Zar 200 OurCity'
};
clientManager.createEntity('FormDTO', defaultData);
But it throws exception:Object doesn't support property or method 'CompanyName'
So what is the correct way to create-entity with initialValues whan entity contain complex type?
Based of what is working in your project it sounds like you are using something like a camelCase strategy for naming your client side properties. If that is not the case please excuse this answer.
If that is the case then why aren't you using camelCased properties when creating your complex types? Seems simple enough -
var defaultData = {
taxYear:0,
unit_A:{
companyName:'ourCompany',
companyAddress:'Zar 200 OurCity'
}
};
clientManager.createEntity('FormDTO', defaultData);
I am using angularjs-rails-resource , in my Rails Angular App.
Account Resources
myApp.factory('Account', ['railsResourceFactory','railsSerializer', function
(railsResourceFactory,railsSerializer) {
return railsResourceFactory({
url: '/accounts',
name: 'account',
serializer: railsSerializer(function () {
this.nestedAttribute('address');
})
});
}]);
UserController.js
function userController($scope,$location,Auth,$rootScope,$http,Useraccount,Account) {
$scope.profileUpdate = function() {
//Useraccount.save(); // THIS WORKS
$scope.account = {}
$scope.account.save() // Throwing error : undefined function save
}
}
UserAccount Service
myApp.service('Useraccount',function(Auth,$location,$rootScope,Account){
var account;
var query = function(){
var promise = Account.query().then(function (results) {
account = results;
}, function (error) {
alert("Went Wrong while fetching User Account!!")
});
return promise;
}
var save = function() {
account.save().then(function (results) {
console.log(results);
}, function (error) {
alert("Went Wrong!!")
});
}
return {
query:query,
save:save
}
})
});
I am not sure why the save function from UserController is not working though I have imported Account resources as dependency. I did same in service , but it was working there. Any clue will be helpful.
You are actually calling the save() method for an empty javascript object. I don't see the point here.
Anyway you need an Angular object to do so. So either load account data from server.
$scope.accounts = Account.query(); // Will be an Array of accounts
Or create new instance of Account
$scope.account = new Account(); // An empty object
I started using knockout.js and i really like it.
I use ASP.Net mvc , jQuery and knockout.js
My question is this:
lets say i have a management screen of a user, the user is my view model
inside the user i want an array of permissions
my user viewModel:
var userViewModelClass = function () {
var self = this;
ko.mapping.fromJS({
ID: "",
permissions: []
}, {}, self);
}
now.. if i do an ajax request to the server and get a JSON back i user the mapping plugin, and everything goes as expected
but... now i want my rendered permissions list to have an action like delete.
so i will need a permission object and then the array of permissions will be an array of permission objects. but how do i do that? how will the mapping plugin know that the object returned to him from the server in an array is actually on object like this one:
function permission() {
var self = this;
this.delete = function () {
};
ko.mapping.fromJS({
name: "",
level: ""
}, {}, self);
}
that's my first part of the question.
the second part:
lets say i got the model with an array of all permissions and they are all of this permission object. now i want each delete button in my view to be bind the the delete function inside the permission object.
using:
data-bind="click: delete"
what is the best implementation for a delete function? i thought about something like: makeing an ajax call to the server which will actually delete the permission from the user. then if the call succeeds remove the current permission from the observable array, then the view will update...
is that a good practice?
thanks!
First part. You need to use mapping options. In your userViewModelClass do this.
var userViewModelClass = function () {
var self = this;
ko.mapping.fromJS({
ID: "",
permissions: []
}, {
permissions: {
create: function(options) {
return new permission(options.data);
}
}
}, self);
}
And modify your permission object like so
function permission(config) {
var self = this;
this.delete = function () {
};
ko.mapping.fromJS($.extend({
name: "",
level: ""
}, config), {}, self);
}
Note I added the extend in so that your default structure will remain and be overwritten by incoming data.
Second part of your question. One possible way would be to pass a reference to the parent in your constructor. So the above mapping options would become
permissions: {
create: function(options) {
return new permission(options.data, self);
}
}
Then your delete could be something like.
this.delete = function () {
$.ajax(deleteurl, yourdata, function(result) {
// success
parent.permissions.remove(self);
}, function() {
// failure
display error message
}
};
EDIT
Alternate way as discussed in comments.
var userViewModelClass = function () {
var self = this;
ko.mapping.fromJS({
ID: "",
permissions: []
}, {
permissions: {
create: function(options) {
return new permission(options.data);
}
}
}, self);
this.delete = function(permission) {
self.permissions.remove(permission);
};
}
data-bind="click: $parent.delete"
Hope this helps.