Create a dynamic meteor collection using a variable - javascript

I am trying to create a dynamic meteor collection using a variable so a new meteor collection will be created everytime an form is submitted and an event is executed. See code below for what I am looking for though is does not work.
(Keep in mind I am still in the early production stages so I have not set up specific server or client side for debugging purposes. Also, disregard any grammatical or structure errors as i just typed this. just how to make it work)
Intended result:
Suppose user 1 meteor id is x533hf4j3i
Suppose user 2 meteor id is jf83jfu39d
OUTCOME: x533hf4j3ijf83jfu39d = new Mongo.Collection('x533hf4j3ijf83jfu39dmessages')
this sample code that DOES NOT WORK
Template.createChat.events({
'submit form': function(event){
event.preventDefault();
var messageRecipientVar = event.target.messageRecipient.value;
var currentUserId = Meteor.userId();
var recipientUserId = Meteor.users.findOne(messageRecipientVar)._id;
var chatCollectionNameVar = {$concat: [currentUserId, recipientUserId]}
var chatCollectionName = {$concat: [currentUserId, recipientUserId, "messages"]}
chatCollectionNameVar = new Mongo.Collection('chatCollectionName');
}
});

Don't do this. Asking how to create dynamic collections comes up periodically with new meteor developers, but it's never the right approach. #david-wheldon has a great description of why not to do this at the bottom of this page.
Just use one collection Messages, containing documents something like this:
{ _id: xxxxxx,
sender: 'x533hf4j3i',
recipient: 'jf83jfu39d',
message: 'Hi there!',
...
timestamp, etc
...
}
Then it depends on your app if a user can view messages they did not send/receive, and if you need filtering on this you would do it server side in a publish function.
Either way, on the Client if you just want the messages between two users you would query like this:
chatMessages = Messages.find(
{$or: [{ sender: 'x533hf4j3i', recipient: 'jf83jfu39d'},
{ sender: 'jf83jfu39d', recipient: 'x533hf4j3i'}
]}).fetch()

Related

Integrating GiroPay and SOFORT via Stripe

I tried to integrate the other offered payments offered by stripe. I followed the docs but it seems I overread something (read everthing like 10 times).
First I activated the payment methods.
I added the library: <script src="https://js.stripe.com/v3/"></script>
I created a Stripe client: var stripe = Stripe('pk_live_512dfvL8d63Kcs9d5Lsp548c6Sp'); (tried this with both test and publishable key)
I added an instance of Elements: var elements = stripe.elements(); (Not using it though)
Depending on the choosen payment something else gets triggered. Well here is my code:
function buyingProcess() {
console.log(choosenPaymentMethod);
if (choosenPaymentMethod == "mastervisa") {
// This works like a charm
} else if (choosenPaymentMethod == "giropay") {
stripe.createSource({
type: 'giropay',
amount: 1099,
currency: 'eur',
owner: {
name: 'Jenny Rosen',
},
redirect: {
return_url: 'https://shop.example.com/crtA6B28E1',
},
}).then(function(result) {
console.log(result);
// handle result.error or result.source
});
}
}
The last console.log function shows me the source object. While using the test key console.log(result.error) stated out, that I have to use the publishable key.
Thanks for any help. I wrote the Stripe Team. yesterday at this time but I apreciate any help. Thanks.
If you are seeing a source object in your console, then you have successfully created a source! The next step is to set up a webhook endpoint, and listen for a source.chargeable event.
Once you have received that your customer has authorized the source to be charged, and you can create a charge on your server using your secret key:
https://stripe.com/docs/sources/best-practices#charge-creation
You can delete var elements = stripe.elements(); as you don't need Elements to create sources, just the Stripe.js library.

Querying a parse table and eagerly fetching Relations for matching

Currently, I have a table named Appointments- on appointments, I have a Relation of Clients.
In searching the parse documentation, I haven't found a ton of help on how to eagerly fetch all of the child collection of Clients when retrieving the Appointments. I have attempted a standard query, which looked like this:
var Appointment = Parse.Object.extend("Appointment");
var query = new Parse.Query(Appointment);
query.equalTo("User",Parse.User.current());
query.include('Rate'); // a pointer object
query.find().then(function(appointments){
let appointmentItems =[];
for(var i=0; i < appointments.length;i++){
var appt = appointments[i];
var clientRelation = appt.relation('Client');
clientRelation.query().find().then(function(clients){
appointmentItems.push(
{
objectId: appt.id,
startDate : appt.get("Start"),
endDate: appt.get("End"),
clients: clients, //should be a Parse object collection
rate : appt.get("Rate"),
type: appt.get("Type"),
notes : appt.get("Notes"),
scheduledDate: appt.get("ScheduledDate"),
confirmed:appt.get("Confirmed"),
parseAppointment:appt
}
);//add to appointmentitems
}); //query.find
}
});
This does not return a correct Clients collection-
I then switched over to attempt to do this in cloud code- as I was assuming the issue was on my side for whatever reason, I thought I'd create a function that did the same thing, only on their server to reduce the amount of network calls.
Here is what that function was defined as:
Parse.Cloud.define("GetAllAppointmentsWithClients",function(request,response){
var Appointment = Parse.Object.extend("Appointment");
var query = new Parse.Query(Appointment);
query.equalTo("User", request.user);
query.include('Rate');
query.find().then(function(appointments){
//for each appointment, get all client items
var apptItems = appointments.map(function(appointment){
var ClientRelation = appointment.get("Clients");
console.log(ClientRelation);
return {
objectId: appointment.id,
startDate : appointment.get("Start"),
endDate: appointment.get("End"),
clients: ClientRelation.query().find(),
rate : appointment.get("Rate"),
type: appointment.get("Type"),
notes : appointment.get("Notes"),
scheduledDate: appointment.get("ScheduledDate"),
confirmed:appointment.get("Confirmed"),
parseAppointment:appointment
};
});
console.log('apptItems Count is ' + apptItems.length);
response.success(apptItems);
})
});
and the resulting "Clients" returned look nothing like the actual object class:
clients: {_rejected: false, _rejectedCallbacks: [], _resolved: false, _resolvedCallbacks: []}
When I browse the data, I see the related objects just fine. The fact that Parse cannot eagerly fetch relational queries within the same call seems a bit odd coming from other data providers, but at this point I'd take the overhead of additional calls if the data was retrieved properly.
Any help would be beneficial, thank you.
Well, in your Cloud code example - ClientRelation.query().find() will return a Parse.Promise. So the output clients: {_rejected: false, _rejectedCallbacks: [], _resolved: false, _resolvedCallbacks: []} makes sense - that's what a promise looks like in console. The ClientRelation.query().find() will be an async call so your response.success(apptItems) is going to be happen before you're done anyway.
Your first example as far as I can see looks good though. What do you see as your clients response if you just output it like the following? Are you sure you're getting an array of Parse.Objects? Are you getting an empty []? (Meaning, do the objects with client relations you're querying actually have clients added?)
clientRelation.query().find().then(function(clients){
console.log(clients); // Check what you're actually getting here.
});
Also, one more helpful thing. Are you going to have more than 100 clients in any given appointment object? Parse.Relation is really meant for very large related collection of other objects. If you know that your appointments aren't going to have more than 100 (rule of thumb) related objects - a much easier way of doing this is to store your client objects in an Array within your Appointment objects.
With a Parse.Relation, you can't get around having to make that second query to get that related collection (client or cloud). But with a datatype Array you could do the following.
var query = new Parse.Query(Appointment);
query.equalTo("User", request.user);
query.include('Rate');
query.include('Clients'); // Assumes Client column is now an Array of Client Parse.Objects
query.find().then(function(appointments){
// You'll find Client Parse.Objects already nested and provided for you in the appointments.
console.log(appointments[0].get('Clients'));
});
I ended up solving this using "Promises in Series"
the final code looked something like this:
var Appointment = Parse.Object.extend("Appointment");
var query = new Parse.Query(Appointment);
query.equalTo("User",Parse.User.current());
query.include('Rate');
var appointmentItems = [];
query.find().then(function(appointments){
var promise = Parse.Promise.as();
_.each(appointments,function(appointment){
promise = promise.then(function(){
var clientRelation = appointment.relation('Clients');
return clientRelation.query().find().then(function(clients){
appointmentItems.push(
{
//...object details
}
);
})
});
});
return promise;
}).then(function(result){
// return/use appointmentItems with the sub-collection of clients that were fetched within the subquery.
});
You can apparently do this in parallel, but that was really not needed for me, as the query I'm using seems to return instantaniously. I got rid of the cloud code- as it didnt seem to provide any performance boost. I will say, the fact that you cannot debug cloud code seems truly limiting and I wasted a bit of time waiting for console.log statements to show themselves on the log of the cloud code panel- overall the Parse.Promise object was the key to getting this to work properly.

How to show the number of user stories/test cases by total, pending, complete, in progress, accepted?

So I saw this app for rally on Github:
https://github.com/RallyApps/DefectSummaryMatrix
And I am trying to make the same thing, except for test cases and user stories, instead of defects. How would I go about doing this? I am pretty new into the rally SDK and kind of lost to be honest, so anything you guys can say would help.
I've been looking at the App.html for this, and I think this part is the part I need to pay attention to cause this is where it gets the information about the defects:
var defectQuery = function() {
var selected = releaseDropdown.getSelectedName();
var releaseQuery = '(Release.Name = "' + selected + '")';
var queryObject = [];
queryObject[0] = { key: 'defectStates', type: 'Defect', attribute: 'State' };
queryObject[1] = { key: 'defectPriorities', type: 'Defect', attribute: 'Priority' };
queryObject[2] = {
key: 'defects',
type: 'Defect',
query: releaseQuery,
fetch: 'FormattedID,Name,State,Priority,ScheduleState,ObjectID,Description,owner,DisplayName,LoginName'
};
rallyDataSource.findAll(queryObject, populateTable);
};
How do I modify this to get information about user stories? I think the type field would be called userStory or something like that, but then what would the key and attributes be? I can't find any documentation on this.
See Rally object model in Web Services API documentation.
User stories are called "HierarchicalRequirement" in the WS API. Click on HierarchicalRequirement object in the object model to go over the attributes.
I suggest that you do not use the DefectSummaryMatrix as a starting point. It is a legacy app that is using legacy AppSDK1. Use AppSDK2 instead. There is an example of multi-type object grid here.

How do I post an HTML class into a mongoDB collection using express/mongoose and client-side JS?

First off my programming knowledge is entirely on the front-end, but I'm experimenting with node, express, mongoose, and mongodb. I'm using someone else's template to try and build an app the right way, but I'm lost when connecting the dots. I have the following jade:
form(method='post', action="/post/comment/" + post.id)
textarea(name='text')
input(type='submit', value='Save')
Combined with this from the routes/posts.js file
app.post("/post/comment/:id", loggedIn, function (req, res, next) {
var id = req.param('id');
var text = req.param('text');
var author = req.session.user;
Comment.create({
post: id
, text: text
, author: author
}, function (err, comment) {
if (err) return next(err);
res.redirect("/post/" + id);
});
});
and this is models/comment.js :
var mongoose = require('mongoose');
var ObjectId = mongoose.Schema.Types.ObjectId;
var createdDate = require('../plugins/createdDate');
var schema = mongoose.Schema({
text: { type: String, trim: true, validate: validateText }
, post: { type: ObjectId, index: true }
, author: String
})
function validateText (str) {
return str.length < 250;
}
schema.plugin(createdDate);
module.exports = mongoose.model('Comment', schema);
Now this works fine, for submitting a comment and saving it in the DB. Problem is, is that I don't want to save a comment, but HTML after a function has manipulated it. So I tried:
var everything = $('.whatever').html();
$.post("/post/comment/:id", everything,
function(){
console.log('html saved!')
}
)
But I got a POST http://localhost:3000/post/comment/:id 500 (Internal Server Error) Now I'm aware that I probably don't have the id variable so I tried pasting in the number that is in the url, and that seemed to go through without error, but than didn't show up in the DB. I'm aware that this may not be a specific question, and that I may be going about this entirely wrong but any general direction would be much appreciated. Thanks.
You seem to have a number of problems here. Try taking a look at the following:
Your router is set to receive posts to "/post/comment/:id", but your post in the last code block is posting to "/post/comments/:id", where comments is plural. This will likely result in a 404. (Check the networks tab of your browser javascript console. It may be silently failing without you realizing it).
Your 500 error is likely coming from the fact that you directly posted ":id", instead of an actual identifier. Many node apps will have an app.param() block set up to validate these parameters, and your friend's template is likely breaking when it doesn't get a number it expects.
The data that you post must match the schema of the model you're saving it to. Any keys that aren't named in the schema will be stripped prior to saving, and in your case, if no keys match, it will just be a default comment instance, and won't save at all.
Hope that helps!

Saving node.js post data to show all records that have been added since the web application was started

I'm working on a web application using node.js that has a form containing basic information about a person. I need to have all records that have been added since the web application was started display on the submit page.
I believe that I need to create an array to store this information but this is where my confusion starts. I'm not sure where to create the array to add information to. I suspect it should be in app.js where I call app.post('/add', routes.add);
I think it should maybe something like this going from an example I found here How do I add a new complex entry to a javascript array?:
// Routes
app.get('/', routes.index);
app.post('/add', routes.add);
var people = [{name, country, date, email, phone}];
people.push({name, country, date, email phone});
However the array looks like it will only hold enough information for 1 person.
Please let me know if my question is not clear enough and I will try to clarify
Thanks in advance!
Edit: I believe that when I am calling routes.add this code is executed from my index.js file
exports.add = function(req, res){
res.render('add', { title: 'Person added',
name: req.body.name,
country: req.body.country,
date: req.body.birthday,
email: req.body.email,
phone: req.body.phone});
};
and in my add.jade file:
h1 Info Added
p Name: #{name}
p Country: #{country}
p Date: #{date}
p Email: #{email}
p Phone: #{phone}
There are a few things to maybe get you started.
Database
I suggest you move the database to another file, that way you may replace it with a 'real' database later. Ie. do something like this:
create a lib directory in app root,
create a db.js in that directory,
put this code in the db.js:
var database = [],
counter = 0;
// add method adds a new object to db.
exports.add = function(person) {
person.id = counter;
counter = counter + 1;
database.push(person);
return id; // we return id, so that we can use it as a reference to this object.
}
// get method retreives the object by id.
exports.get = function(id) {
return database[id]; // this will return undefined if there is no such id
};
exports.list = function(){
return database;
}
Now you have a database.
Controllers
You use the db in other files like this:
var people = require('lib/db');
// or if you're in a routes directory,require('../lib/db') or appropriate path
people.add({name: 'Sarah'}); // returns 0
people.add({name: 'Zlatko'}); // returns 1
people.get(1); // returns {name: 'Zlatko'}
Now in your routes/index.js you can include your database and have this to save or retreive an user or all users. Somehing similar to your exports.add:
var id = people.add({name: req.body.name, email: req.body.email});
res.render('add', people.get(id));
You can also create a 'people' view and just pass it {people: people.list()} object as parameters array.
I didn't include any validation, checking, anything ,to make the example more clear. This db can hold more then one person, and it's enough to get you started. And I think it is clear in what it does.
I hope this helps.

Categories

Resources