I have written a simple AngularDart app that queries the a webservice. The user enters text into a search box and each new character in the search box fires a query to the webservice. This works fine.
However, I want to update the view once the request is returned. This does not work. The result is received (I can print this to the console). But the result (a list of products) is not rendered to the display.
How do I update the view from the controller when I get a result?
Below is the main.dart file:
library products;
import 'package:angular/angular.dart';
import 'package:angular/application_factory.dart';
import 'dart:html';
import 'dart:convert';
class MyAppModule extends Module {
MyAppModule() {
type(ProductController);
}
}
void main() {
applicationFactory()
.addModule(new MyAppModule())
.run();
/* Listen to the search box */
querySelector('#searchBox').onInput.listen(startQuery);
}
void startQuery(Event e) {
String queryText = (e.target as InputElement).value;
ProductController.query(queryText);
}
final String SERVER_URL = "http://127.0.0.1:3000/query/";
@Controller(
selector: '[products]',
publishAs: 'prods')
class ProductController {
static List<Product> _products;
ProductController() {
_products = [];
/* This is only for testing, this works */
query('beer');
}
static void query(String query) {
String url = SERVER_URL + query;
var request = HttpRequest.getString(url).then(_onDataLoaded);
}
/* When the query result returns, this is run */
static void _onDataLoaded(String responseText) {
Map responseJSON = JSON.decode(responseText);
_products = _getProductList(responseJSON['results']);
/* This fire always, even when user enters text */
print(_products);
}
/* Convert the Map to a Product List */
static List<Product> _getProductList(List<Map> productMapList) {
List<Product> list = [];
for (var objProduct in productMapList) {
list.add(new Product.fromObject(objProduct));
}
return list;
}
List<Product> get products => _products;
}
class Product {
String name;
String company;
Product.fromObject(var objProduct) {
name = objProduct['name'];
company = objProduct['company'];
}
}
Below is the body of the html file:
<body>
<!-- The Search Area -->
<div search-area class="search-area">
<div class="col span_1_of_3"></div>
<div class="col span_1_of_3">
<input type="text" name="name" id="searchBox" placeholder="Search" autocomplete="off" tabindex="1">
</div>
<div class="col span_1_of_3"></div>
</div>
<!-- The Results Area -->
<div products class="results-area">
<div ng-repeat="product in prods.products">
<!-- List all products -->
<div class="col span_1_of_3">
{{product.name}}
</div>
</div>
</div>
<script src="packages/shadow_dom/shadow_dom.min.js"></script>
<script type="application/dart" src="myapp.dart"></script>
<script type="text/javascript" src="packages/browser/dart.js"></script>
</body>
The answer is kind of simple.
ProductController() {
_products = [];
/* This is only for testing, this works */
query('beer');
/* This Code is new: this can be init'd here instead of in main */
querySelector('#searchBox').onInput.listen(startQuery);
}
The reason is that AngularDart holds ProductController object in it's scope and previously I created a new ProductController object, that was outside of the scope and so changes were not updated to the view.