0

Im struggling to insert array of strings into mongo db collection.

its coming up with an error insert failed: Error: Address must be a string

EDIT

I am generating dynamic form fields for CCs and Attendees, and need to save those values in an array.

here the jQuery snippet:

$(function(){
  $(document).on('focus', 'div.form-group-options div.input-group-option:last-child input', function(){
    var sInputGroupHtml = $(this).parent().html();
    var sInputGroupClasses = $(this).parent().attr('class');
    $(this).parent().parent().append('<div class="'+sInputGroupClasses+'">'+sInputGroupHtml+'</div>');
  });
  $(document).on('click', 'div.form-group-options .input-group-addon-remove', function(){
    $(this).parent().remove();
  });
});

html:

<form class="row form-horizontal newMeeting"> 
  <div class="form-group form-group-options col-xs-11 col-md-3" id="cc">
    <div class="input-group input-group-option col-xs-12">
      <input type="text" name="option[]" class="form-control" id="cc" placeholder="CCs">
      <span class="input-group-addon input-group-addon-remove">
        <span class="glyphicon glyphicon-remove"></span>
      </span>
    </div>
  </div>

  <div class="form-group form-group-options col-xs-11 col-md-3">
    <div class="input-group input-group-option col-xs-12">
      <input type="text" class="form-control" id="attendees" placeholder="Attendees">
      <span class="input-group-addon input-group-addon-remove">
        <span class="glyphicon glyphicon-remove"></span>
      </span>
    </div>
  </div>

  <div class="row no-print">
    <div class="col-xs-12">     
      <input type="submit" value="Save" class="btn btn-primary pull-right">
    </div>
  </div>
</form>

my schema:

Emails = new Mongo.Collection('emails');


EmailSchema = new SimpleSchema({

 "attendeesEmail": {
  type: [Object],
  optional: true
},  
"attendeesEmail.$.address": {
  type: String,
  regEx: SimpleSchema.RegEx.Email
},
ccEmails: {
  type: [Object],
  optional: true
},
"ccEmails.$.address": {
  type: String,
  regEx: SimpleSchema.RegEx.Email
}
});

Emails.attachSchema(EmailSchema);

event:

Template.form.events({
'submit .newMeeting': function(event) {
var cc = $('#cc').serializeArray();
var attendees = $('#attendees').serializeArray();
});

Insert:

Emails.insert({
  attendeesEmail: [{address: attendees}],
  ccEmails: [{address: cc }]
});

console.log(attendees); prints [Object] error message says insert failed: Error: 0 must be a string

I've tried few solutions, but couldn't get it working, any suggestions would be appreciated.

3 Answers 3

0

The .serializeArray() method creates a JavaScript array of objects, ready to be encoded as a JSON string

So cc, attendees are not Strings

You can try to use toSource() method:

var cc = $('#cc').serializeArray().toSource();
var attendees = $('#attendees').serializeArray().toSource();

Or use JSON.stringify method

var cc = JSON.stringify($('#cc').serializeArray());
var attendees = JSON.stringify($('#attendees').serializeArray());

But the toSource method doesn't working on Chrome,IE. It works on Firefox
API Here

   <!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("button").click(function(){
    var x = $("form").serializeArray();
    alert(JSON.stringify($("form").serializeArray()));
    $.each(x, function(i, field){
        $("#results").append(field.name + ":" + field.value + " ");
    });
});
});
</script>
</head>
<body>

<form action="">
  First name: <input type="text" name="FirstName" value="Mickey"><br>
  Last name: <input type="text" name="LastName" value="Mouse"><br>
</form>

<button>Serialize form values</button>

<div id="results"></div>

</body>
</html>

Sign up to request clarification or add additional context in comments.

1 Comment

this doesn't solve the issue, as the data is stored as an empty array
0

You can solve the issue with updating your events like this.

Template.form.events({
  'submit .newMeeting': function(event) {
     var cc = $('#cc').val();
     var attendees = $('#attendees').val();
});

The issue is occurring due to serializeArray() methods which converting your string to an object, But if you still want to use the serializeArray methods then you can do like this

Template.form.events({
  'submit .newMeeting': function(event) {
     var cc = $('#cc').serializeArray().value;
     var attendees = $('#attendees').serializeArray().value;
});

1 Comment

thanks for suggestion, first code snippet doesnt address my issue as it stores only single value, in my case I am creating dynamic form fields for cc and attendees. hence will need to have an array of those values. The second solution saves the data as an empty array
0

The way you are explicitly defining your schema is wrong, in particular the attendeesEmail and ccEmails properties. If you intend it to be an array of objects then you need to define the array of objects keys explicitly as follows:

Emails = new Mongo.Collection('emails');

EmailSchema = new SimpleSchema({
    "attendeesEmail": {
        type: [Object],
        optional: true
    },  
    "attendeesEmail.$.address": {
        type: String,
        regEx: SimpleSchema.RegEx.Email
    },
    ccEmails: {
        type: [Object],
        optional: true
    },
    "ccEmails.$.address": {
        type: String,
        regEx: SimpleSchema.RegEx.Email
    }
});

Emails.attachSchema(EmailSchema);

Once you have this schema defined then you can implement the insert using the following example as guideline. This assumes user enters a semicolon delimited list of email addresses in the text input. It uses the template scope provided in the event handler which makes code a lot less error prone by scoping to the template and this approach is a slightly cleaner way to do forms in Meteor without all the global jQuery references.

Template code:

<template name="foo">
    <form id="myform" class="newMeeting">
        <input type="text" name="attendees" />
        <input type="text" name="cc" />
        <input type="submit" id="submit" />
    </form>
</template>

Event handler:

Template.foo.events({   
    'submit form': function(event, template) {
        event.preventDefault();

        var attendees = template.find("input[name=attendees]"),
            cc = template.find("input[name=cc]"),
            attendeesList = attendees.split(';').map(function (email){ 
                return { address: email } 
            }),
            ccList = cc.split(';').map(function (email){ 
                return { address: email } 
            });


        // Do form validation

        var data = {
            attendeesEmail: attendeesList,
            ccEmails: ccList
        };

        // Clear form
        attendees.value = "";
        cc.value = "";

        Emails.insert(data, function(err) { /* handle error */ });
    }
});

3 Comments

thanks. I have just updated the question, im gererating dynamic form fields for CC and Attendees and need to save them into array
i've tried to put it as an object [Object], that was the first thing i've tried and it kept throwing an error insert failed: Error: 0 must be a string.
I have amended my schema, but i cant get the implementation working. can you advice me on it please? in my case the user doesnt enters a semicolon delimited list of email addresses in the text input. instead user inputs an email in brand new dynamically generated field as shown in my question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.