3

I'm new to app development in angular-meteor, and I'm struggling to make changes to a database from the client side. I've completed most of the angular-meteor tutorial with success, but now that I'm trying to start a new project and adapting concepts from the tutorial, I'm running into problems.

Problem. Users fill out a form, and when they click "add," the form should save data to the database. On the same page, I've included a list that shows all database entries (typical "element in elements" loop in html list). However, when I click "add," after filling out the form, the new entry is added to the list for a split second and then disappears. The same behavior occurs when I click on a "delete all" button, everything disappears for a moment and then restores. The data that persists is whatever was in the database before adding/deleting.

Attempts to troubleshoot. I can access the collection with "meteor mongo," and the values which persist are in the collection. I can add to the collection or delete from it from the command line (EDIT: and changes are reflected on the client's end). The entries submitted on the client side are not added to the database. I initiated the database with a server-side startup function with the condition if (Videos.find().count() === 0). I thought that perhaps the database was just reinitializing itself every time, but the behavior persists when the initializing code is commented out. Adding autopublish the project doesn't solve the problem. EDIT: Google Chrome doesn't have any errors in console before or after submitting.

Relevant Code. I'm using this repository as a starting point.

/client/views/submit/submit.controller.js

angular.module("app").controller("SubmitCtrl", ['$scope', '$meteor',
  function($scope, $meteor){

    $scope.videos = $meteor.collection(Videos).subscribe('videos');

  }
]);

/client/views/submit/submit.ng.html

<form>
  <label>URL</label>
  <input ng-model="newVideo.linkurl">
  <label>Description</label>
  <input ng-model="newVideo.description">   
  <button ng-click="videos.save(newVideo); newVideo='';">Add</button>
</form>

<ul>
  <li ng-repeat="video in videos">
    {{video.linkurl}}
    <p>{{video.description}}</p>
  </li>
</ul>  

/model/collections.js Videos = new Mongo.Collection("videos");

/server/publications/videos.js

Meteor.startup(function () {
  if (Videos.find().count() === 0) {
    var videos = [
      { 'linkurl': 'https://www.youtube.com/watch?v=O7zewtuUM_0',
        'description': '1st video'},
      { 'linkurl': 'https://www.youtube.com/watch?v=KSzuiqVjJg4',
        'description': '2nd video'},
    ];
    for (var i = 0; i < videos.length; i++)
      Videos.insert(videos[i]);
  };
});

Meteor.publish("videos", function () {
  return Videos.find();
});

The only other file I feel is really relevant here is /client/app.routes.js, but it is quite long and I've changed very very little in it (from about page to submit page, essentially). I also haven't included the controller or view responsible for deleting items, as it seems redundant.

As far as my limited knowledge goes, everything seems like it should be working; consequently, I have the feeling the solution is probably staring at me in the face. Do you have any suggestions on next steps to troubleshoot this problem?

2
  • Can you post your code? That would be the most helpful. Commented Jul 20, 2015 at 3:30
  • Edited original post. Thank you for checking it out! Let me know if there's anything else you'd like to see. Commented Jul 20, 2015 at 4:22

1 Answer 1

5

the new entry is added to the list for a split second and then disappears.

This is caused by latency compensation. Basically the client-side database processes it before the server, to make operations occur faster. This is a very helpful feature, but can be hard to debug if you don't totally grasp how it works.

I assume you have the insecure package removed? To test if this is the issue, run meteor add insecure and see if your app is working now.

If the app only runs when insecure is installed, I think what you need to do is allow writes to the database.

Videos.allow({
  insert: function () {
      // condition where user has write access, return true to allow
      if (Meteor.user()) {
          return true;
     }
   },
  update: function () {},
  remove: function () {}
});

I hope it works!

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

2 Comments

Wow, that did it! What an easy solution, thank you so much. I spent so much time trying other things, but I believe I was really close to figuring this out--I was just looking into .allow a few minutes ago. I hope someone else finds this useful!
Great! I can understand why Meteor comes with insecure pre-installed, and why allows aren't defaulted to true, but I think they should provide some kind of helpful error message in the server console when write access fails. Don't forget to close the issue with a check.

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.