1

Note: The code below is just logic, so no parameters are defined. Although they are defined and being used actively in the same javascript file i'm in.

I'm new to javascript/angularjs (I don't even know what code this is) and as of now it's really throwing me a curveball because of the syntax and everything else going on. I have a main function in my dateTimeService.js file being called that returns another function that returns a true/false value based on if store is open or closed using logic below.

app.factory("dateTimeService", function() {

    return { 
        isHelperOpen: function(hoursString) {
            if (openTime <= nowTime && nowTime <= closeTime)
                  return true;
            else
                  return false;}
    }
}

How can I display a value such as "Open" or "Closed" based on the true/false value being returned by one of those functions? How is the html displayed? Do I create another function to do this? Any help is appreciated.. Thanks in advance!

<div class="availability">{{isHelperOpen(item)}}</div> --this is my long shot
6
  • Can you show us the code for the controller that is in charge of the page where that HTML snippet lives? Commented Dec 8, 2015 at 3:26
  • <span ng-show="isHelperOpen(foo)">Open</span><span ng-hide="isHelperOpen(foo)">Closed</span> Commented Dec 8, 2015 at 3:26
  • @PauloScardine - It didn't work, would the foo values be just true/false? Commented Dec 8, 2015 at 3:37
  • @user1403582 are you wanting the whole dateTimeService.js file? Commented Dec 8, 2015 at 3:38
  • No, not the service, the controller that is in charge of this portion of the page. Do you have the application properly bootstrapped? i.e. you are defining an app module, you have an ng-app directive, you have ng-controller directives, etc? Commented Dec 8, 2015 at 3:43

3 Answers 3

1

Assuming your application is properly bootstrapped and you can call into your service from your controller, here is a greatly simplified fiddle that demonstrates what you want to do.

http://jsfiddle.net/90hozqr1/1/

The HTML:

<body ng-app="myApp">
  <div>
    <div ng-controller="MyController">
      <div>
        <span>{{callServiceWith(true) | displayBool}}</span>
        <span>{{callServiceWith(false) | displayBool}}</span> 
      </div>
    </div>
  </div>
</body>

The Javascript:

var myApp = angular.module("myApp", []);

myApp.factory("dateTimeService", function() {
    return { 
        isHelperOpen: function(hoursString) {
            return hoursString
        }
    }
})

myApp.controller("MyController", function($scope, dateTimeService) {
    $scope.callServiceWith = function(bool){
        return dateTimeService.isHelperOpen(bool);
    }
})

myApp.filter("displayBool", function(){
  return function(input) {
    if(input) {
      return "Open"
    } else {
      return "Closed"
    }
  }
})

Things to notice, there is a function in scope that is calling into the service: callServiceWith and it is being called from the template. The output is being run through a custom filter called displayBool.

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

3 Comments

You would think this would be simple to implement but i'm having a hard time at that even. Thanks for the help!
I'm curious why you'd put a method on the controller that calls the service rather than just inject the service in the filter like I did in my answer? Is there any performance overheads? After working with angular for almost 2 years, I've come to really try to keep the controllers very lightweight.
You’re right in this case, since this is a simple service that isn’t doing anything complicated or making any requests. I guess I was biased when I wrote this example, because the services in the projects I work on tend to make requests and/or do a lot of processing. Controllers should be lightweight, but filters should be even more lightweight. To me, conceptually, a filter should only be about transforming an input to an output, and controllers should be about marshalling data. Injecting anything more than a simple helper service like this one into a filter would raise red flags.
1

You can use the ng-if:

 <span ng-if="isHelperOpen(foo)">Open</span>
 <span ng-if="!isHelperOpen(foo)">Closed</span>

or you can try:

 <span ng-show="isHelperOpen(foo)">Open</span>
 <span ng-hide="isHelperOpen(foo)">Closed</span>

or you can use filter.

1 Comment

ng-if has performance issues: it removes/inserts the element in the DOM, and this is a very expensive operation.
1

I'd recommend an angular filter for something like this. It keeps your rendered value separate from your data value and it also helps keep your DOM & view controller much cleaner:

HTML

<div class="availability">{{item | helperOpenFilter}}</div>

Angular Filter

.filter( 'helperOpenFilter', function(dateTimeService){
    return function (obj){
       return dateTimeService.isHelperOpen(obj) ? 'Open' : 'Closed';
    }
}

4 Comments

I like this.. Where would the .filter go? Inside the scope of app.factory("dateTimeService", function() { or inside the scop of isHelperOpen: function(hoursString) {
Why would some consider this unorthodox? Based on my understanding, this is the perfect use for filters. Simple mapping from one value to another value for display purposes.
@user3258366 you would define the filter via the angular.filter( 'filterName', function(...){ }). NG Docs here - docs.angularjs.org/guide/filter
@user1403582 honestly I dunno why I said that.... I guess it's because I haven't seen too many examples of <elem>{{ objValue | filter }}</elem>. It's usually on string values like so <elem>{{ stringValue | filter }}</elem>. I should amend that so as not to scare off people seeking a similar solution.

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.