Kendo UI scheduler create - angularjs

Im having problems with the kendo scheduler. Im using it together with AngularJS.
When i create an event and click save, first of the create window wont close and when i manually close it the event is not there. But if i reload the page the event is shown there, so it is getting saved to the database.
Scheduler dataSource:
var dataSource = {
transport: {
read: read,
create: create,
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
},
},
schema: {
model: {
id: "occurrenceId",
fields: {
occurrenceId: { from: "occurrenceId", type: "number" },
title: { from: "title", defaultValue: "No title", validation: { required: true } },
start: { type: "date", from: "start" },
end: { type: "date", from: "end" },
description: { from: "description" },
recurrenceId: { from: "RecurrenceID" },
recurrenceRule: { from: "RecurrenceRule" },
recurrenceException: { from: "RecurrenceException" },
isAllDay: { type: "boolean", from: "IsAllDay" }
}
}
}
};
And here is the create function:
function create(data) {
var occurrence = {
"title": data.data.title,
"start": data.data.start,
"end": data.data.end,
"description": data.data.description,
"recurrenceId": data.data.recurrenceId,
"recurrenceRule": data.data.recurrenceRule,
"recurrenceException": data.data.recurrenceException,
"isAllDay": data.data.isAllDay,
"ownerId": $scope.resource.id
}
$http({
method: 'POST',
url: '/api/occurrences',
data: JSON.stringify(occurrence),
contentType: "application/json"
}).success(function (response) {
response.data
});
}

Try returning the inserted data (including the generated ID) from your create function. On your http post's success, it doesn't seem to be doing anything meaningful.
From Kendo-UI data source API reference: The remote service must return the inserted data items and the data item field configured as the id must be set. For example if the id of the data item is ProductID the "create" server response must be [{ "ProductID": 79 }].

Related

How do i modify a raw data object returned by an ExtJS AJAX proxy into a JSON object to be consumed by a Tree Store

In an effort to create a treepanel, i configure it with a treestore whose AJAX proxy url receives json data i have no control of. But using Ext.data.reader.Json's transform property invokable before readRecords executes, gives an option to modify the passed raw (deserialized) data object from the AJAX proxy into a modified or a completely new data object. The transform config, gives the code snippet below:
Ext.create('Ext.data.Store', {
model: 'User',
proxy: {
type: 'ajax',
url : 'users.json',
reader: {
type: 'json',
transform: {
fn: function(data) {
// do some manipulation of the raw data object
return data;
},
scope: this
}
}
},
});
I would please like an example on how to go about modifying the return JSON object
[
{
"id": 3,
"attributes":
{},
"name": "user_one",
"login": "",
"email": "user_one#ats",
"phone": "0751223344",
"readonly": false,
"administrator": false,
"password": null
},
{
"id": 4,
"attributes":
{},
"name": "user_two",
"login": "",
"email": "user_two#ats",
"phone": "0751556677",
"readonly": false,
"administrator": false,
"password": null
}
]
into a JSON object fit for a treestore.
The hierarchical tree is to be rendered to show which user is under which admin using a condition administrator==true from the returned JSON, then a second AJAX request that returns that admin's users shown here.
[
{
"user_id": 3,
"admin_id": 1,
},
{
"user_id": 4,
"admin_id": 2,
}
]
Is the data nested at all? Otherwise why use a treepanel instead of a grid? To your question though, it'll depend on how you configure your treepanel but it would probably be something like this:
transform: {
fn: function(data) {
var treeRecords = Ext.Array.map(data, function(i){
return {
text: i.name,
leaf: true
//any other properties you want
}
});
var treeData = {
root: {
expanded: true,
children: treeRecords
}
};
return treeData;
},
scope: this
}

Cannot log data from JSON-server API with GraphQL

I have built an API with JSON-server and I am trying to fetch the data from it using React-Apollo Client.
I'm trying to log the data from API on the console with Query tag, restructure and print the data variable using console.log().
I have no idea why the function is getting print via console.log().
I have the current setup:
JSON server is running on PORT 4000
Server is running on PORT 5000
Client is running on PORT 3000
I am already using CORS tool
Below is my component:
const BOOKS_QUERY = gql`
query BooksQuery {
books {
title
author
editionYear
}
}
`;
<Query query={BOOKS_QUERY}>
{({ loading, error, data }) => {
if (loading) return <h4>Loading...</h4>;
if (error) console.log(error);
console.log(data);
return <h1>test</h1>;
}}
</Query>
The content below is code for my schema:
const BookType = new GraphQLObjectType({
name: 'Book',
fields: () => ({
id: { type: GraphQLInt },
title: { type: GraphQLString },
author: { type: GraphQLString },
editionYear: { type: GraphQLInt }
})
});
//Root Query
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
books: {
type: new GraphQLList(BookType),
resolve(parent, args) {
return axios.get('http://localhost:4000/books').then((res) => res.data);
}
},
book: {
type: BookType,
args: {
id: { type: GraphQLInt }
},
resolve(parent, args) {
return axios.get(`http://localhost:4000/books/${args.id}`).then((res) => res.data);
}
}
}
});
module.exports = new GraphQLSchema({
query: RootQuery
});
API:
{
"books": [
{
"id": "1",
"title": "Java How To Program",
"author": "Deitel & Deitel",
"editionYear": "2007"
},
{
"id": "2",
"title": "Patterns of Enterprise Application Architecture",
"author": "Martin Fowler",
"editionYear": "2002"
},
{
"id": "3",
"title": "Head First Design Patterns",
"author": "Elisabeth Freeman",
"editionYear": "2004"
},
{
"id": "4",
"title": "Internet & World Wide Web: How to Program",
"author": "Deitel & Deitel",
"editionYear": "2007"
}
]
}
I only expect the API data to be logged on console.
Later I will render that data on screen.

Mongoose Update array in a document does not work as expected

I'm scratching my head since a couple day on how to update the content of an array with Mongoose.
Here is my schema to begin with:
const playedGameSchema = new Schema ({
created: Date,
updated: Date,
game: {
type: Schema.Types.ObjectId,
ref: 'game'
},
creator: {
id: {
type: Schema.Types.ObjectId,
ref: 'user'
},
score: Number
},
partners: [{
id: {
type: Schema.Types.ObjectId,
ref: 'user'
},
score: Number
}]
});
module.exports = mongoose.model('PlayedGame', playedGameSchema);
Basically, what I want to achieve is to, at the same time:
- Update the creator.score (successful with dot notation).
- Update the score key for each partner (unsuccessful).
Here is the result of a document created:
{
"creator": {
"id": "5b8544fa11235d9f02a9b4f1",
"score": 0
},
"_id": "5bb6375f5f68cc5c52bc93ae",
"game": "5b45080bb1806be939bfde03",
"partners": [
{
"_id": "5bb637605f68cc5cafbc93b0",
"id": "5b85497111235d677ba9b4f2",
"score": 0
},
{
"_id": "5bb637605f68ccc70ebc93af",
"id": "5b85497111235d677ba9b4f2",
"score": 0
}
],
"created": "2018-10-04T15:53:03.386Z",
"updated": "2018-10-04T15:53:03.386Z",
"__v": 0
}
As I said, I was able to change the score of the score creator by passing something like { "creator.score": 500 } as a second parameter, then I switch to trying to update the array.
Here is my lambda function to update the score for each partner:
export const update: Handler = (event: APIGatewayEvent, context: Context, cb: Callback) => {
context.callbackWaitsForEmptyEventLoop = false;
const body = JSON.parse(event.body);
let partnersScore: object = {};
if(body.update.partners) {
body.update.partners.forEach((score, index) => {
const key = `partners.${index}.$.score`;
partnersScore = Object.assign(partnersScore, { [key]: score});
console.log(partnersScore);
});
}
connectToDatabase().then(() => {
console.log('connected', partnersScore)
PlayedGame.findByIdAndUpdate(body.id, { $set: { partners: partnersScore } },{ new: true})
.then(game => cb(null, {
statusCode: 200,
headers: defaultResponseHeader,
body: JSON.stringify(game)
}))
.catch(err => {
cb(null, {
statusCode: err.statusCode || 500,
headers: { 'Content-Type': 'text/plain' },
body: err
})});
});
}
Which passes a nice { 'partners.0.$.score': 500, 'partners.1.$.score': 1000 } to the $set.
Unfortunately, the result to my request is a partners array that contains only one empty object.
{
"creator": {
"id": "5b8544fa11235d9f02a9b4f1",
"score": 0
},
"_id": "5bb6375f5f68cc5c52bc93ae",
"game": "5b45080bb1806be939bfde03",
"partners": [
{
"_id": "5bb63775f6d99b7b76443741"
}
],
"created": "2018-10-04T15:53:03.386Z",
"updated": "2018-10-04T15:53:03.386Z",
"__v": 0
}
Can anyone guide me into updating the creator score and all partners score at the same time?
My thoughs about findOneAndUpdate method on a model is that it's better because it doesn't require the data to be changed outside of the BDD, but wanting to update array keys and another key seems very difficult.
Instead, I relied on a set/save logic, like this:
PlayedGame.findById(body.id)
.then(game => {
game.set('creator.score', update.creatorScore);
update.partners.forEach((score, index) => game.set(`partners.${index}.score`, score));
game.save()
.then(result => {
cb(null, {
statusCode: 200,
headers: defaultResponseHeader,
body: JSON.stringify(result)
})
})
.catch(err => {
cb(null, {
statusCode: err.statusCode || 500,
headers: { 'Content-Type': 'text/plain' },
body: JSON.stringify({ 'Update failed: ': err })
})});
})

Update a complex object on Backand using $http PUT

I am using Backand to provide the database and REST api for my Angular app.
I am working on a capability for users to make edits to a complex object, which should then be updated on the database. Straightforward enough...
The object looks a bit like this:
obj = {
id: 1, // assigned by the db
name: "My List",
tasks: [
{ id: 1, desc: "Task 1" },
{ id: 2, desc: "Task 2" },
...
]
}
For the update ($http PUT) call, I would like to use params: { deep: true } as a shortcut to minimise code and $http calls.
The problem at the moment is that while the PUT command updates the "master" object in the database, the edited "child" objects are not updated, but appended as new child objects.
For instance, if I try to update the master and child objects in one call:
$http({
method: 'PUT',
url: baseUrl + 'lists/' + list.id,
params: {
deep: true
},
data: {
id: 1,
name: "My To Do List",
tasks: [
{ id: 1, desc: "New Description for Task 1" },
{ id: 2, desc: "New Description for Task 2" }
]
}
}).then( .... );
the database doesn't update the child objects, it appends them. Here's how the resulting object is in the database:
list = {
id: 1,
name: "My To Do List", // Updated correctly
tasks: [
{ id: 1, desc: "Task 1" },
{ id: 2, desc: "Task 2" },
{ id: 3, desc: "New Description for task 1" }, // Added not updated
{ id: 4, desc: "New Description for task 2" } // Added not updated
]
}
I have made sure that the child objects' ids are correct.
Is there any way to do this succinctly or am I resigned to doing it in multiple stages? Does deep = true even work with PUT? The Backand docs don't mention it.
Backand identifies existing objects according to their
{
__metadata: {id: "6"}
}
When you "GET" an object from Backand it contains such a metadata.
When you "PUT" an object without the metadata id, Backand threats it as a new object.
So either use the same deep object that you originally got or add the metadata id.
$http({
method: 'PUT',
url: baseUrl + 'lists/' + list.id,
params: {
deep: true
},
data: {
"__metadata": { "id": "1" },
id: 1,
name: "My To Do List",
tasks: [
{ "__metadata": { "id": "1" }, id: 1, desc: "New Description for Task 1" },
{ "__metadata": { "id": "2" }, id: 2, desc: "New Description for Task 2" }
]
}
}).then( .... );
To delete tasks children in the "PUT" request you have to add overwrite=true to the params
params: {
deep: true,
overwrite: true
}

loopback angular sdk get all users with a certain role

I'm currently stuck on getting all the users with certain role, for example admin users, in one angular SDK controller.
according to the docs of strongloop. what I did was:
User.find({
filter: {
include: [{'relation':'roles', 'scope': {
where:{
name:'admin',
}}
}],
},
}, function(list) {
console.log(list);
});
But the list i got is all the users, the non-admin users are included too. On the server side it is the default codes, i didn't change them.
{
"name": "user",
"plural": "Users",
"base": "User",
"properties": {
},
"relations": {
"roles": {
"type": "belongsTo",
"model": "RoleMapping",
"foreignKey": "principalId"
}
},
"acls": [],
"methods": []
}
Could you tell me what I made wrong? I don't want to loop through all the "list" from that query and filter the admin users, because it is a very huge list of users, but admin is for only 2 or 3 persons.
Here is the solution of what i did, from the common/models/user.js, i created a remotemethod, called "getUsersByRole", and only accept "role", which is the name of the role:
User.remoteMethod('getUsersByRole', {
accepts: [
{ arg: 'role', type: 'string', required: true },
],
returns: {arg: 'users', type: 'string'},
http: {
verb: 'get',
path: '/byrole/:role'
}
});
then here is the function of it:
User.getUsersByRole = function(role, cb) {
var loopback = require('loopback');
var Role = loopback.getModel('Role');
var userIdList = [];
Role.findOne({include:'principals', where: {name:role}}, function(err, role) {
role.principals(function(err, principals) {
for (var i = 0; i < principals.length; i++) {
userIdList.push(parseInt(principals[i].principalId));
}
if (userIdList.length > 0) {
User.find({where: {id: {inq: userIdList}}}, function(err, users) {
cb(err, users);
});
} else {
cb(err, false);
}
});
});
}
then run the lb-ng command to generate the service for angular client side, then run:
User.getUsersByRole({role:rolename}, function(list) {
});
in the controller.
Can you run the query from the role instead?
Role.find({
filter: {
where: {name:'admin'},
include: {'relation':'users'}
},
}, function(list) {
console.log(list);
});

Resources