0

I'm rendering dynamic content in my javascript template (EJS). After that, I receive through socket.io some part of the content for update. I was wondering if there was a proper way to do this without using some kind of $eval or $parse function.

Here's the code to render the template :

var data = [
    "0":{
        "id": "0",
        "title": "Data 0",
        "name": "Name of Data 0",
        "description": "Desc of Data 0"
    },
    "1":{
        "id": "1",
        "title": "Data 1",
        "name": "Name of Data 1",
        "description": "Desc of Data 1"
    },
    "2":{
        "id": "2",
        "title": "Data 2",
        "name": "Name of Data 2",
        "description": "Desc of Data 2"
    }   
];

<% for(var i=0; i < data.length; i++) {%>
    <div class="wrapper">   
        <h1><%=data[i].title%></h1>
        <p><%=data[i].name%></p>
        <p><%=data[i].description%></p>
    </div>
<% } %> 

Now, my socket.io app will send to this page one of the data with new content; for example

"1":{
    "id": "1",
    "title": "New Data 1",
    "name": "New Name of Data 1",
    "description": "New Desc of Data 1"
},

How could I update the correct DOM node in angular ? And if needed what do I need to change in the data sent by socket.io ?

I used to start this kind of code but this looks very ugly :

<script>
<% for(var i=0; i < data.length; i++) {%>
    $scope.Data_<%=data[i].id%>_title = "<%=data[i].title%>";
    $scope.Data_<%=data[i].id%>_name = "<%=data[i].name%>";
    $scope.Data_<%=data[i].id%>_desc = "<%=data[i].description%>";
<% } %>
</script>

And the HTML :

<% for(var i=0; i < data.length; i++) {%>
    <div class="wrapper">   
        <h1>{{Data_<%=data[i].id%>_title}}</h1>
        <p>{{Data_<%=data[i].id%>_name}}</p>
        <p>{{Data_<%=data[i].id%>_description}}</p>
    </div>
<% } %> 
3
  • Just to be clear... your sample doesn't look like it is using an AngularJS ngRepeat but another templating language. You are looking for an AngularJS example though right? It probably just would involve wrapping the code which receives the socket.io update in $apply Commented May 14, 2014 at 1:31
  • Hi, I could initiate the HTML with ngRepeat without problem. I'm stuck with the update, dunno how to do it Commented May 14, 2014 at 1:40
  • To be clear, how can I update the correct div (in the example it will be the second one "id:1") and keep the others with the first data object Commented May 14, 2014 at 1:48

1 Answer 1

2

OK, as I mentioned in my comment above, I believe you just need to make use of the $apply() method of an AngularJS $scope which triggers binding updates in Angular templates via a $digest cycle. When using Angular to make HTTP service calls or built-in Angular directives to handle user input this most often happens for you automatically. However, if you are using socket.io for data updates you'll need to tell Angular when to trigger updates by using $apply() (or $digest()... read the docs for the differences).

Here's a jsfiddle example showing how $apply() could be used to update your data.

NOTE: Your sample data above is actually not a valid javascript array. In the sample note how I've used a nearly identical javascript object as the data source instead.

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

2 Comments

Thanks for the answer! This looks better. However, in your example you use $scope.data["1"] = {. In real case, I will not be aware of which data id is going to be updated. So with your code, I have to first parse my new data object to get the correct id and set it in the $scope.data[correct_id] = { or is there an other way ?
Yeah, you would need some additional logic to know compare the updated data to the old data and replace the keys/elements of the old data that had been updated.

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.