Session Set and Get in Meteor - javascript

I am trying to dynamically get and set a pageTitle for my sample Meteor app, ideally I'd like to use jQuery, but any other solution would be good too.
I am trying to do it the rough way by setting a session when a certain div class exists on the page, but it's not working for some reason.
Basically, I have this:
Template.layout.helpers({
pageTitle: function() { return Session.get('pageTitle'); }
});
And I want to do something like
if ($('section').hasClass('single')) {
Session.set('pageTitle', 'Post Page');
}
Any idea ho to make this work? thanks!

You need to call it in a controller or the templates rendered section like this:
Template.layout.helpers({
pageTitle: function() {
return Session.get('pageTitle');
}
});
// set when a page template renders
Template.posts.rendered = function() {
setPageTitle("Blog Posts");
};
// or with Iron Router on *every* route using some sort of variable
Router.onBeforeAction(function() {
var someDynamicValue = "FOO";
setPageTitle(someDynamicValue);
});
// or in an IronRouter Controller
PostsController = RouteController.extend({
onBeforeAction: function() {
setPageTitle("Blog Posts");
}
});
// helper function to set page title. puts a prefix in front of page, you
// could opt set a boolean to override that
function setPageTitle(titleName) {
var prefix = "My Site - ";
if ($('section').hasClass('single')) {
Session.set('pageTitle', prefix + titleName);
}
}

As #Kuba Wyrobek pointed out, I needed to use the Template.layout.rendered function.
Here's a snippet that works
Template.postsList.rendered = function(){
Session.set('pageTitle', 'Listing Page')
};

Related

Ember js - how to create a shared uitility

I am writing code to detect breakpoints via js using match media. In plain js, I know how to create a separate utility for this and consume it, but in Ember, how do I go about it, would I need to create a helper or something else.
Plain JS code:
define('viewportDimension', function() {
var viewportSize ={
mqMaxTablet : '959px',
isTablet: function(){
if(matchMedia){
var mq = window.matchMedia("(max-width:" + this.mqMaxTablet+ ")");
mq.addListener(this.viewportChanged);
this.viewportChanged(mq);
}
},
viewportChanged: function(mq){
if(mq.matches){
return true;
}
}
};
return viewportSize;
});
Ember Controller:
isTablet: function (){
viewportDimension.isTablet();
}.property('')
I understand the above code will not work. I dont know how to make it more Ember'ish type. The "isTablet" property should be set to true, as soon as the media query match is done.
Started converting my plain js to emberish (as below), but dont know how to proceed.
define('viewportDimension',function(){
var viewportSize = Ember.Object.extend({
isTablet: function(){
alert("1");
}.property('')
});
return viewportSize;
});
Ember.Application.initializer({
name: 'viewport-dimension',
initialize: function(container,app){
require('viewportDimension',function(object){
app.ViewportDimension = object
})
}
})
Please take a look at simple-breakpoint-detector

Pass data between controllers while pageload without using $rootscope in angularjs

I have 2 controllers like below,
app.controller('ParentMenuController',
function ($scope,MenuService) {
$scope.contentLoaded = false;
$scope.showButton = false;
$scope.showButton = MenuService.getStatus();
});
Controller2:
app.controller('ChildMenuController',
function ($scope,MenuService) {
MenuService.setStatus(true);
});
Service:
app.factory('MenuService', function ($q,$http) {
var status= false;
var setStatus=function(newObj){
status=newObj;
};
var getStatus=function(){
return status;
};
return {
getStatus:getStatus,
setStatus:setStatus
};
});
I am not able to set the status to true, but the below line of coding is not at all executing, so the status is always false.
$scope.showButton = MenuService.getStatus();
On button click or any action from user i can trigger the event, but my requirement is while page load, the button should not be visible. When childMenu controller executes, then parent controller button should be visible. I dont want to use $broadcast which requires $rootscope.
Note: My controller and html has hundereds of lines. I just pasted here required code for this functionality. ChildMenuController(childMenu.html) has separate html and ParentMenuController(parentMenu.html) has separete html.
So $scope.showButton is not available in ChildMenucontroller. Both html is used as directive. Main html is index.html.
See this sample:
http://plnkr.co/edit/TepAZGOAZZzQgjUdSpVF?p=preview
You need to use a wrapper object so that it's properties are changed instead of the main object.
app.controller('ParentMenuController',
function ($scope,MenuService) {
$scope.contentLoaded = false;
$scope.showButton = MenuService.getStatus();
});
app.controller('ChildMenuController',
function ($scope,MenuService) {
MenuService.setStatus(true);
});
app.factory('MenuService', function ($q,$http) {
var status= {value:false};
var setStatus=function(newObj){
status.value=newObj;
};
var getStatus=function(){
return status;
};
return {
getStatus:getStatus,
setStatus:setStatus
};
});
It's exactly the same as your code, but state is now an object with a value property. The state object is always the same one so that when the value is changed in the service the changes are propagated to everyone that has ever requested that object.
Actually your service is getting called and this piece of line is executing
$scope.showButton = MenuService.getStatus();
but once your child controller got loaded you are only setting the status but in order to show button you should getStatus after setting it
Like this,
app.controller('ChildMenuController', function($scope, MenuService) {
MenuService.setStatus(true);
$scope.$parent.showButton = MenuService.getStatus();
});
this will set the button to true and it will be shown.
I have done a sample with your code please take a look into it
DEMO

How to force Template.dynamic to re render

I read and tried a lots of solution but i wasn't able to force the Template.dynamic to render again.
In html >>
<body>
{{> Template.dynamic template=Template}}
</body>
In Meteor.isClient >>
Template.body.helpers({
'Template': function() {
return page.template;
}
});
I have a function on hashchange event which will change the value of page.template, the event works fine and value will changed every time, but i can't force the Template.dynamic to render again.
page.template is string
I have a function page.getTemplate() > return page.template just to try all options
I'm using the last version of Meteor 1.1.0.2
I am not sure how your app is organized but this should be an easy task. Just use a ReactiveVar to save your active template-name you wish to have selected.
I made a simple MeteorPad for you. Hopefully this is what you are looking for.
http://meteorpad.com/pad/oPhK4KqjiSztRSa9K/SimpleDynamicTemplateSwitch
Cheers
Tom
Before start , i changed some objects , page.template is now object and page.template.get() will return string, but i don't use it, i pass the template name in Sessions, and this is my page.template.set()
page.template.set = function(name) {
Session.set('template', name);
};
Well i found the answer, you need to set a dependency to Sessions, i have done this so far
Template.body.helpers({
'Template': function() {
return Session.get('template');
}
});
Edited
Because of client hack i decided to changed something (you can change the session in console, and i want my router decide to which template should be shown)
page.template.set = function(name) {
page.template.name = name;
Session.set('template', name);
};
page.template.get = function() {
return page.template.name;
};
Template.body.helpers({
'Template': function() {
return Session.get('template') ? page.template.get() : page.template.get();
}
});

Session.set() upon route event in Meteor

I have this functionality associated with clicking a button:
'click .single-speaker-info a': function(ev, speaker){
ev.preventDefault();
Session.set('selectedDocId', this._id);
}
But I'd like it to happen upon hitting this route
Router.route('speaker', {
path:'/speakers/:_id',
template: 'speaker',
data: function(){
return Speakers.findOne(this.params._id);
},
//my attempted solution
selectedDocId: function(){
Session.set('selectedDocId', this._id);
}
});
But I can't find any documentation on how to execute a method on a route.
Here is the Template.helper Im using to get the property Im setting
Template.speaker.helpers({
editingDoc: function(){
return Speakers.findOne({_id: Session.get('selectedDocId')});
}
});
But I can't find any documentation on how to execute a method on a route.
Iron Router offers a number of hooks:
onRun <-- probably what you need
onRerun
onBeforeAction
onAfterAction
onStop
You could use Template.x.rendered, once the page is rendered, any code in that block will be executed. Of course this would not be in your router.
In your case:
Template.speaker.rendered = function() {
//Get data from router
var data = Router.current().data();
Session.set('selectedDocId', data._id);
}

Emberjs common router events

I'm trying to join common events to a route, and then extend the route as needed
Like this:
App.ScrollTopRoute = Ember.Route.extend({
renderTemplate: function() {
console.log('Hi this works ?');
window.scrollTo(0, 0);
}
});
Then I extend the route:
App.TodoRoute = App.ScrollTopRoute.extend({
model: function(params) {
return App.Todo.find(params.todo_id);
}
});
The problem is the events inside ScrollTopRoute are not launch
So which is the best way to join common routines for routes?
You are doing DOM related operations which should go into the didInsertElement of a view.
So for your window.scrollTo(0, 0) to work it should be defined in such a hook, assuming you have a todos template than this should work.
App.TodosView = Ember.View.extend({
didInsertElement: function() {
window.scrollTo(0, 0);
}
});
In the case you need common code to be executed in different classes one possible way is to create a Mixin and mix it into the classes that need it.
For example:
App.CommonMixin = Ember.Mixin.create({
myCommonFunction: function() {
console.log('this works');
}
});
App.ScrollTopRoute = Ember.Route.extend(App.CommonMixin, {
...
// myCommonFunction is available here
});
App.AnotheScrollTopRoute = Ember.Route.extend(App.CommonMixin, {
...
// myCommonFunction is available here
});
As for the Mixin, see here for a simple demo.
Hope this answers your question, if not let me know so I can improve it further.

Categories

Resources