I would like to push the data into the array after a 2 second delay each time.
//working code
$scope.GetData = function(){
DataFactory.GetCategories()
.success(function(data,status){
$scope.TheArray.push(data);
})
}
//This doesnt work. No data is shown in html
$scope.GetData = function(){
DataFactory.GetCategories()
.success(function(data,status){
setTimeout(function() {
$scope.TheArray.push(data);
}, 2000);
})
}
EDIT:
$scope.GetData = function(){
DataFactory.GetCategories()
.success(function(data,status){
$timeout(function () {
$scope.ChatHistory.push(JSON.parse(JSON.parse(data)));
}, 3000);
})
}
Use $timeout instead of setTimeout, and it will run fine. When using setTimeout, you will have to do $scope.$apply to propogate your changes to your view/model, but $timeout does that magic for you, so you don't have to worry about it.
More info on $timeout here
EDIT:
You will have to add $timeout as a dependency, like below
angular.module('myApp').controller('MyController', function($timeout) {
$scope.GetData = function(){
DataFactory.GetCategories()
.success(function(data,status){
$timeout(function () {
$scope.ChatHistory.push(JSON.parse(JSON.parse(data)));
}, 3000);
})
}
})
Related
Why isn't this reactive? And more importantly how can it be made reactive?
I'd like the data to be saved in Mongo and used in the template. I could use a ReactiveVar or ReactiveDict. Do I need two copies of the data?
Doesn't Suspects.findOne('bruce') return a reactive object already? I tried putting the human answer directly on Bruce, but it didn't trigger an update.
The events fire, log(this) shows bruce's answer was changed, but the template doesn't re-render. What's the good way to do this?
http://meteorpad.com/pad/KoH5Qu7Fg3osMQ79e/Classification
It's Meteor 1.2 with iron:router added:
<head>
<title>test</title>
</head>
<template name="question">
{{#unless isAnswered 'human'}} <!-- :-< I'm not reacting here -->
<div>Sir, are you classified as human?</div>
<button id="no">No, I am a meat popsicle</button>
<button id="smokeYou">Smoke you</button>
{{else}}
<div> Classified as human? <b>{{answers.human}}</b></div>
{{/unless}}
</template>
And the JavaScript:
// Why isn't this reactive?
if (Meteor.isClient) {
Template.question.helpers({
isAnswered: function (question) { // :-< I'm not reactive
var suspect = Template.instance().data;
return (typeof suspect.answers[question] !== 'undefined');
}
});
Template.question.events({
'click #no': function () {
this.answers.human = "No"; // :-< I'm not reactive
console.log(this);
},
'click #smokeYou': function() {
this.answers.human = "Ouch"; // :-< I'm not reactive
console.log(this);
}
});
}
// Collection
Suspects = new Meteor.Collection('suspects');
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
Suspects.upsert('bruce', { quest: 'for some elements', answers: {}});
});
Meteor.publish('suspects', function() {
return Suspects.find({});
});
}
// Iron Router
Router.route('/', {
template: 'question',
waitOn: function() {
return Meteor.subscribe('suspects');
},
data: function() {
return Suspects.findOne('bruce');
}
});
Thanks :-)
The events are not actually updating the reactive data source (the db record). Instead of doing:
Template.question.events({
'click #no': function () {
this.answers.human = "No";
}
});
The event needs to perform a database action, either through a direct update or through a Meteor.call() to a Meteor.method. For example:
'click #no': function(){
Suspects.update('bruce', {'answers': {'human': 'no'}});
}
If you use this pattern, you will also need to set the correct allow and deny rules to permit the update from client code. http://docs.meteor.com/#/full/allow. Methods generally end up being a better pattern for bigger projects.
Also, I'm not sure off the top of my head that Template.instance().data in your helper is going to be reactive. I would use Template.currentData() instead just to be sure. http://docs.meteor.com/#/full/template_currentdata
Very close you just need to use ReactiveVar by the sound of it it pretty much explains what it's :) http://docs.meteor.com/#/full/reactivevar
and here's how to use it
if (Meteor.isClient) {
Template.question.onCreated(function () {
this.human = new ReactiveVar();
});
Template.question.helpers({
isAnswered: function (question) {
return Template.instance().human.get();
}
});
Template.question.events({
'click #no': function (e, t) {
t.human.set('No');
console.log(t.human.get());
},
'click #smokeYou': function(e, t) {
t.human.set('Ouch');
console.log(t.human.get());
}
});
}
UPDATE: if you're using a cursor I usually like to keep it on the template level not on iron router:
if (Meteor.isClient) {
Template.question.helpers({
isAnswered: function (question) {
return Suspects.findOne('bruce');
}
});
Template.question.events({
'click #no': function (e, t) {
Suspects.update({_id: ''}, {$set: {human: 'No'}});
},
'click #smokeYou': function(e, t) {
Suspects.update({_id: ''}, {$set: {human: 'Ouch'}});
}
});
}
I'm a total newbie to Meteor. I'm trying to create a proof of concept using Meteor where updates to the Mongo oplog get displayed to the browser screen.
For now, I'm trying to adapt the simple-todos to this purpose. I got the server logging updates to the terminal but no idea how to transfer this to the client browser screen?
if(Meteor.isClient) {
// counter starts at 0
Session.setDefault('counter', 0);
Template.hello.helpers({
counter: function () {
return Session.get('counter');
}
});
Template.hello.events({
'click button': function () {
// increment the counter when button is clicked
Session.set('counter', Session.get('counter') + 1);
}
});
}
if(Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
var Test = new Mongo.Collection('test');
var query = Test.find({});
var init = true;
query.observeChanges({
added: function(id, fields) {
if(!init)
console.log('doc inserted');
},
changed: function(id, fields) {
console.log('doc updated');
},
removed: function() {
console.log('doc removed');
}
});
init = false;
});
}
Define collection for both - server and client:
//collection Test for client and server
var Test = new Mongo.Collection('test');
if (Meteor.isClient) {
//subscribe for collection test
Meteor.subscribe('test');
Template.hello.helpers({
test: function() {
var query = Test.find();
query.observeChanges({
added: function(id, fields) {
console.log('doc inserted');
},
changed: function(id, fields) {
console.log('doc updated');
},
removed: function() {
console.log('doc removed');
}
});
return query;
}
});
}
if (Meteor.isServer) {
Meteor.publish('test', function() {
return Test.find();
});
}
For more complex app you should structure your app into multiple directories and files. Read about it in Meteor docs.
How do I add mobile swipe left/right events in Meteor?
I've tried...
Template.NAME.events({
'swipeleft': function(){ //DO SOMETHING }
})
I've also tried using chriswessels/meteor-hammer package,
Template.NAME.gestures({
'swipeleft .img-contain': function(){
alert("test")
},
'tap': function(){
alert("test")
},
})
Neither of those methods worked.
Did you try the hammer:hammer package?
Seems like work pretty good.
You can configurate like this.
Template.NAME.rendered = function(){
$('body').hammer({
drag_min_distance:1,
swipe_velocity:0.1
});
};
And this Events
Template.NAME.events({
'swipeleft #hammerDiv': function(e, t) {
e.preventDefault();
//Do cool stuff here
},
'swiperight #hammerDiv': function(e, t) {
e.preventDefault();
//Do cool stuff here
}
});
I have asked this question on the google forum for AngularJS and haven't heard about it until now. Can someone help me understand what is going on here?
I am trying to periodically refresh a resource and it doesn't seem to be working. I have tracked it until the fact that the promise has been obtained from $http service but the XHR request is never created and fired when the method is invoked in setTimeout. However, if I do the same without setTimeout everything seems to be working just fine.
Working JSFiddle: http://jsfiddle.net/hponnu/Z62QN/2/
window.root_module = angular.module("MyApp", ['ngResource']);
function MainController($scope, $resource) {
$scope.buttonClick = function () {
var res = $resource("http://www.google.com");
res.get({}, function (response) {
alert("response");
}, function (err) {
alert("error");
});
}
}
Broken JSFiddle: http://jsfiddle.net/hponnu/H8aEt/10/
window.root_module = angular.module("MyApp", ['ngResource']);
window.count = 0;
function MainController($scope, $resource) {
$scope.buttonClick = function () {
setTimeout(function () {
alert("timeout: " + window.count);
var res = $resource("http://www.google.com");
res.get({},
function (response) {
alert("response: " + window.count);
window.count++;
}, function (err) {
alert("error: " + window.count);
window.count++;
});
}, 1000);
}
}
As you will clearly see in the broken jsfiddle the error alert is not fired for the first request unless a click event is triggered by click on the button again. I have started noticing this from AngularJS 1.1.4
Any ideas/suggestions?
PS: https://groups.google.com/forum/#!topic/angular/t28mazamT0E is the link for the Google groups thread.
You should always use Angularjs's $timeout instead of setTimeout().
function MainController($scope, $resource, $timeout) {
$scope.buttonClick = function () {
$timeout(function () {
...
}, 1000);
}
}
I'm trying to simply return what I request in PHP to JSON.
My problem is that each Stock is not yet completed.
Indeed, it is the "render" but "this.collection.models" is not yet completed because the request is not yet finished.
What should I do to correct this problem, wait until the request is finished so that the loop is done correctly.
Thank you in advance
var Article = Backbone.Model.extend({});
var Articles = Backbone.Collection.extend({
model:Article,
url: function() {
return _BASE_URL+'/sync/getLastArticles';
},
initialize:function () {
this.fetch();
}
});
var ArticlesView = Backbone.View.extend({
template:$('#articles').html(),
initialize:function () {
this.collection = new Articles();
this.render();
},
render:function () {
console.log(this.collection);
var that = this;
_.each(this.collection.models, function (item) {
console.log(item);
}, this);
},
renderArticle:function () {
;
}
});
You render before the fetch is done. What you want to do, is to wait for the fetch to complete and then render. Now how would you get notification of when the fetch is done? You have 2 options:
The success function (Not recommended by me)
// ArticlesView
initialize: function() {
_.bindAll(this); // Don't forget to BIND
this.collection = new Articles();
this.collection.fetch({
success: this.render
});
}
Now when the fetch has been successful, render is called. This however can cause scoping problems and Backbone.js offers a much nicer alternative to callback functions: events.
Event callback (prefer this)
// ArticlesView
initialize: function() {
_.bindAll(this);
this.collection = new Articles();
this.collection.on('reset', this.render); // bind the reset event to render
this.collection.fetch();
}