0

I want to store the URLs from the user to the database. So far I have created Session variables in the client side and store the values there and I pass them to the server using Meteor methods.

These are the methods that do this

screenshotsURLS: function (sshots) {
   check(sshots, [String]);
   // Products.update({},{$set:{screenShots:sshots}});
   scs = sshots.slice();
      console.log(scs);
  },
  previewImageUrl: function (url) {
   check(url, String);
   pi = url;
   console.log(pi);
  },
  sourceCodeUrl: function (url) {
   check(url, String);
   zip = url;
   console.log(zip);
  }

These three variables "scs, pi, zip" are initialized like this:

var zip;
var pi;
var scs = [];

My code works fine and i manage to store the values of the variables inside my collection, the problem is when i open the website from two browsers and call the functions one and the other. the variables above will have the values of the last one who called the function.

they are stores in the collection like this:

submitPost: function (app) {
    // Console.log('new App:', app);
    check(app, {
      title: String,
      description: String,
      category: String,
      price: Number
    });
    var knownId = Products.insert(app);
    Products.update({ _id: knownId }, { $set:{previewImage: pi, sourceCode: zip }});

  }

and for the scs am returning the value using the autoValue

screenShots: {
    type: [String],
    autoValue: function() {
      return scs;
    }
  }

for the submitPost, it is called from the quickForm in the html file this way

 {{> quickForm collection="Products" id="submitPostForm"
  type="method" meteormethod="submitPost" omitFields="createdAt, previewImage, screenShots, sourceCode, userID"}}

once the user clicks submit button, the submitPost will be triggered.

The AutoForm.hooks implementation

AutoForm.hooks({
    submitPostForm: {  //<--- this is the id of your form
        before: {  //<-- before submit
            methodName: function (doc) {  //<-- get the doc to be submitted

                //HERE YOU CAN MANIPULATE THE FORM FIELDS BEFORE SUBMIT
                var previewImage = Session.get("previewImageURL")
                if (previewImage) {
                    doc.previewImage = previewImage;
                }

                var sourceCode = Session.get("sourceCodeURL");
                if (sourceCode) {
                    doc.sourceCode = sourceCode;
                }

                var screenshots = Session.get("screenshots");
                if (screenshots) {
                    doc.screenShots = screenshots;
                }
                return doc;
            }
        },
        onSuccess: function (formType, result) {

        },
        onError: function (formType, error) {

        }
    }
});

I believe my AutoForm.hooks doesn't work for some reason because when i try to console.log("previewImage") nothing happens!

How do i separate the variables "scs, pi, zip" for every user so that they don't contradict?

Behrouz Riahi
  • 1,751
  • 2
  • 21
  • 42
  • I can see why this is happening, but I'm unclear why you are storing these values in the server's memory prior to writing to the database - this isn't a normal pattern. Why not just pass them as arguments to `submitPost`? – David Weldon Mar 08 '16 at 18:15
  • @DavidWeldon am not sure if it is possible to pass them as argument to submit post, if it is possible this will solve my problem. The reason i don't think it is possible is that am getting the value of these variables from the client side by using the methods i included in the question. Am i wrong that it is not possible? are there a way i can pass them to submitPost? i hope it is possible – Behrouz Riahi Mar 08 '16 at 20:02
  • Maybe I'm misunderstanding the problem. It seems like you are saying: (1) client stores value X in a Session var, (2) client calls a method to store X in the server's memory, (3) client calls `submitPost` on the server which reads X from it's own memory. Why not just skip step 2 and pass X from the client in the call to `submitPost` as the 2nd argument (after `app`)? If it's in a Session var, you can read it from anywhere in the app at the time of the call. – David Weldon Mar 08 '16 at 20:12
  • @DavidWeldon i don't think it is possible because of the way submitPost method is called, i edited my question to show how it is called, please correct me of am wrong – Behrouz Riahi Mar 08 '16 at 20:20
  • That's only a limitation if you restrict yourself by passing in the method name when creating the form. I'm not an autoform expert, but after a quick scan of the docs, it seems like you can just do a [normal](https://github.com/aldeed/meteor-autoform#normal) submit handler and call the method with the correct values. – David Weldon Mar 08 '16 at 20:26
  • @DavidWeldon okay if i change my code and use the normal way, i still don't think it will work because of the way am passing those values, when the user uploads the previewImage picture for example, this method will be triggered Meteor.call('previewImageUrl', Session.get("previewImageURL")); unless if i can pass the value as an argument from the previewImageUrl method. – Behrouz Riahi Mar 08 '16 at 20:41
  • @DavidWeldon if only there is a way where i can create variables for each user logged in, this will solve my problem, unless if there is another way i can implement that i don't know of – Behrouz Riahi Mar 08 '16 at 20:42

1 Answers1

1

Seems to me you are making things complicated for no reason:

if the data is submitted by the user (i.e. preview image url or code url) then you should submit all of this at once in your submit form.

if the data is generated somehow (like if you upload an image, and then need to get the url for that image to show in preview) then upload, and return the image url is the upload return callback, to make it available to your form.

when you submit the form, submit all at once with the info generated from the server and sent back to the client.

so whatever you do on your method calls, return the ids in the method callback by simply using return pi; or return url; or whatever it is you need to return from that call.

EDIT:

It seems like the question pertains to passing extra params to the form.

This is done using the form hooks:

{{> quickForm
                collection="Product"
                id="create"
                type="method"
                meteormethod="insertProduct"
                doc=doc
                }}



AutoForm.hooks({
    create: {  //<--- this is the id of your form
        before: {  //<-- before submit
            method: function (doc) {  //<-- get the doc to be submitted

                //HERE YOU CAN MANIPULATE THE FORM FIELDS BEFORE SUBMIT
                var image = Session.get('imagePreview');
                if (image) {
                    doc['preview'] = image;
                }
                return doc;
            }
        },
        onSuccess: function (formType, result) {

        },
        onError: function (formType, error) {

        }
    }
});
MrE
  • 19,584
  • 12
  • 87
  • 105
  • am new to meteor and don't know hot to use the callback so am checking them now, will approve your answer if it worked, thanks :) – Behrouz Riahi Mar 08 '16 at 21:00
  • the Method calls can return data: just use `return ;` Then on the client side, when you call the method, do `Meteor.call("methodName', params, function(error, data) { if (!error) {console.log(data); } });` full doc here: http://docs.meteor.com/#/full/meteor_call – MrE Mar 08 '16 at 21:18
  • based on what i understood, using callbacks i can use the return value of the method in the client. i actually passed those values from the client to the server so they actually available on the client without calling the method. if you meant it other way let me know please, and correct me if i misunderstood the callbacks – Behrouz Riahi Mar 08 '16 at 21:23
  • if you have a way where i can use those values from the client to submit them at once in the submitPost method please let me know, this will solve my problem – Behrouz Riahi Mar 08 '16 at 21:25
  • I don't understand your problem here: you have the variables on the client, to submit them in your submitPost, just pass them as parameters, either as one object (by packing all the params into an object) or as individual parameters. `Meteor.call('myMethod', {app: app, pi:pi, url:url, image:image}, function(err,data){});` or `Meteor.call('myMethod', app, pi, url, image, function(err,data){});` – MrE Mar 08 '16 at 21:43
  • ah, i see... yo may be wondering how to do this in the form: add the fields to the form, and pass the values in the form hooks. I will update the answer. – MrE Mar 08 '16 at 21:46
  • yes, i didn't knew how to do it with the form, will try your solution now, one question only, for this line doc['preview'], preview refers to the element name inside the document? if yes, isn't it supposed to be this way doc.preview? please confirm with me :) – Behrouz Riahi Mar 08 '16 at 22:02
  • doc['preview'] or doc.preview, same thing really. http://stackoverflow.com/questions/4968406/javascript-property-access-dot-notation-vs-brackets – MrE Mar 08 '16 at 22:11
  • you put doc=doc inside the {{quickForm}}, what does it refer to? the doc inside AutoForm.hooks? – Behrouz Riahi Mar 09 '16 at 02:10
  • for some reason the AutoForm.hooks doesn't work with me, i updated the question and added the way i implemented the AutoForm.hooks, please can you take a look at it to see if am missing something there? – Behrouz Riahi Mar 09 '16 at 02:23
  • it was a silly mistake i found it out in the inspect elements in google chrome (typo mistake), its working fine thanks to you, thanks a lot, accepted your answer :) – Behrouz Riahi Mar 09 '16 at 02:49