0

My end goal is creating a table that has sortable columns. I am currently following a tutorial and trying to apply it to my project, but it seems the way I have my code set up that this won't work. I haven't found many tutorials that intersect with my use case with Flask and Angular.

The issue I am having now is that the scope ends at where I am defining the controller. I need items defined by flask's templating system to be added to the angular model.

My flask app is returning json that is consumed by the templating system(Jinja2). Here is my html file. You can see that I have tried to define an "artist" model via ng-model for each artist in the dict of artists.

<div class="artist-table-container" ng-controller="ArtistTableCtrl">
<table class="table artist">
    <tr>
        <th class="artist-table-header"></th>
        <th class="artist-table-header">Artist Name</th>
        <th class="artist-table-header">Number of Albums Released</th>
        <th class="artist-table-header">Most Recent Album</th>
        <th class="artist-table-header">Top Track</th>
    </tr>
    {% for artist in artists%}
    <tr ng-model="artist">
        <td><div class="artist-img-sml"><img class="artist-cover-sml" src="imgs/cover.png" height="64" width="64"><img src={{artist.col_img}} height="64" width="64"></div></td>
        <td>{{artist.name}}</td>
        <td>{{artist.num_albums}}</td>
        <td>{{artist.last_album}}</td>
        <td>{{artist.top_track}}</td>
    </tr>
    {% endfor %}
</table>
</div>

The obvious disconnect seems to be the fact that I am using the templating rather than ng-repeat. However is there a way that I can add these artist html elements to the model after the fact rather than using ng-repeat?

Here is my "ArtistTableCtrl" controller that I have defined...

/* Controllers */
var sweetMusicApp = angular.module('sweetMusicApp', []);
sweetMusicApp.controller('ArtistTableCtrl', function($scope){
    console.log($scope.artist);
    console.log($scope);
});

and the console output (unsuprisingly)...

undefined
b {$$childTail : null, $$childHead: null, $$nextSibling:null,
    $$watchers: null, $$listeners:Object...}

2 Answers 2

2

Firstly, you need to understand that Angular's and Flask's templating system will collide, since both use the same interpolation operator.

So you need to change either one, I'd recommend the client's. You can do this in your app.js:

    // Changing interpolation start/end symbols.
    .config(function($interpolateProvider, $httpProvider){         
        $interpolateProvider.startSymbol('[[').endSymbol(']]');
    })

Now you can use Angular's scope elements with [[ and ]].

Secondly, you're right about the Flask scope ending before Angular's. Basically, Flask templating applies to it's templates and not the static files where I'm assuming your angular code is situated. (if you have app.js, controllers.js, services.js etc.)

Now, when you talk about storing some data fetched from the server in your Angular scope variables (this might be from context passed when template was loaded), you must understand that Angular works best with a REST backend. So if you have API's that can fetch the data, that works best for Angular. You achieve this with a simple GET/POST request in Angular.

Although, there is another (dirty) way to get the Flask templating variables in Angular:

Define input hidden elements in your template that Flask loads:

<input type="hidden" value="{{variable}}" id="var1"/>

Now, you can have access to this element via Angular in this manner:

$scope.var1 = document.getElementById("var1");

Note: This should be only used when you need some data that is only available in the context of the page rendering request. Ideally, you should be having API's to fetch this kind of data.

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

1 Comment

Thank you for your detailed response! It really helped clear things up for me.
0

It looks like you are mixing Server and Angular Client side concepts. This is what I believe you should be doing:

/* Controllers */
var sweetMusicApp = angular.module('sweetMusicApp', []);
sweetMusicApp.controller('ArtistTableCtrl', function($scope, artistService){
  $scope.artists = artistService.fetchArtists();  //service which makes http call to the artists endpoint
});

Your template should use ng-repeat:

<div class="artist-table-container" ng-controller="ArtistTableCtrl">
<table class="table artist">
    <tr>
        <th class="artist-table-header"></th>
        <th class="artist-table-header">Artist Name</th>
        <th class="artist-table-header">Number of Albums Released</th>
        <th class="artist-table-header">Most Recent Album</th>
        <th class="artist-table-header">Top Track</th>
    </tr>
    <tr ng-repeat="artist in artists">
        <td><div class="artist-img-sml"><img class="artist-cover-sml" src="imgs/cover.png" height="64" width="64"><img src={{artist.col_img}} height="64" width="64"></div></td>
        <td>{{artist.name}}</td>
        <td>{{artist.num_albums}}</td>
        <td>{{artist.last_album}}</td>
        <td>{{artist.top_track}}</td>
    </tr>
</table>
</div>

Comments

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.