Aral Roca Aral Roca - 7 months ago 45
Javascript Question

Angular 1.5 Component: passing a function

Is it possible to passing a function to a component and call this function inside the component passing a parameter?

Example:

List of posts

<post-list posts="blog.posts"
loading="blog.loadingPosts"
get-post-url="blog.getPostUrl"
is-user-authenticate="blog.user">
</post-list>


getPostUrl is a function (inside the container controller):

const getPostUrl = (postId) => {
const protocol = $location.protocol();
const host = $location.host();
const port = $location.port();

return protocol + "://" + host + "" + (port !== 80 ? ":" + port : "") + "/blog/post/" + postId;
};


List of posts: component

const PostList = {
"bindings": {
"posts": "<",
"loading": "<",
"getPostUrl": "&", //Function getPostUrl
"isUserAuthenticate": "<"
},
"template": `<div>
<div class="col-md-9 text-center" data-ng-if="$ctrl.loading">
<i class="fa fa-spinner fa-spin fa-2x"></i>
</div>

<div class="col-md-9 posts" data-ng-if="!$ctrl.loading">
<div data-ng-repeat="post in $ctrl.posts">
<post creation-date="{{post.creationDate}}"
content="{{post.content}}"
post-url="{{$ctrl.getPostUrl(post.creationDate)}}"
is-user-authenticate="$ctrl.user">
</post>
</div>
</div>
</div>`,
"transclude": false
};

angular
.module("blog")
.component("postList", PostList);


In this line:

post-url="{{$ctrl.getPostUrl(post.creationDate)}}"
I want to call the function passing a parameter and this function is returning a string.

In post component (not PostList) the postUrl is a string attribute
@
.

But... Is not working!


angular.js:13550 Error: [$interpolate:interr] Can't interpolate: {{$ctrl.getPostUrl(post.creationDate)}}
TypeError: Cannot use 'in' operator to search for 'blog' in 1459329888892
Error Link


Is it possible to do it? And how?

Thank you so much!

Answer

If you want to call the function from inside a component and have it return a value then you need two-way binding:

"bindings": {
  "posts": "<",
  "loading": "<",
  "getPostUrl": "=", // <-- two-way binding
  "isUserAuthenticate": "<"
},

However, this is probably not very good idea. Consider passing data to component rather than making component request data from outside. This will make much better isolated component.