I have a Dart WebComponent
that obtains information periodically from a web service. I'd like to inject the web service into the component and have the component decide when to call the web service (this will allow me to prototype all the UI code using a mock web service with no HTTP call until the service is written).
The issue I'm having is that the web service object I'm sending to the WebComponent
seems to be null until the page is rendered. I'm not exactly sure when the service reference is passed to the page, but it seems to happen after the page is constructed since the value is null in the WebComponent
constructor, but I can see that the value is instantiated when the page itself is rendered. How can I be notified that the service object is now available to the page so I can call the web service?
Follow up question: Is passing the service reference into the WebComponent
like I am below a bad practice? If so, what should I do instead to separate the mock implementation so I can inject the real web service later without changing any code.
Here's my base Dart page:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Dart Prototype</title>
<link rel="stylesheet" href="dart_prototype.css">
<link rel="import" href="location_container.html">
</head>
<body>
<h1>Dart Prototype</h1>
<div id="location_management_container">
<location-container location-service="{{applicationContext.locationService}}" count="{{startingCount}}"></location-container>
</div>
<script type="application/dart">
import 'package:web_ui/web_ui.dart';
import 'package:dart_prototype/dart_prototype_library.dart';
final ApplicationContext applicationContext = new ApplicationContext(
new WebService()
);
int startingCount = 5;
main() {
print('main initializing');
print(applicationContext);
print(applicationContext.locationService);
}
</script>
<script src="packages/browser/dart.js"></script>
</body>
</html>
Here's the code for location-container
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<element name="location-container">
<template>
<div>
<ul id="todo-list">
<li>hi there!</li>
<li>{{count}}</li>
<li>{{locationService}}</li>
</ul>
</div>
</template>
<script type="application/dart">
import 'package:web_ui/web_ui.dart';
import 'package:dart_prototype/dart_prototype_library.dart';
class LocationContainer extends WebComponent {
@observable
WebService locationService;
@observable
int count;
LocationContainer() {
print('in loc container constructor');
print(locationService);
print(count);
}
created() {
print('created!');
print(locationService);
print(count);
}
}
</script>
</element>
</body>
</html>
Here's the code for ApplicationContext and WebService
part of prototype_library;
class ApplicationContext {
final WebService locationService;
ApplicationContext(
this.locationService);
}
class WebService {
final Factory _objectFactory;
WebService(this._objectFactory);
Future call(String url) {
throw new UnimplementedError();
}
}
And here's the result of my print strings statements to the console
Invalid CSS property name: -webkit-touch-callout
main initializing
Instance of 'ApplicationContext'
Instance of 'WebService'
in loc container constructor
null
null
created!
null
null
And here's what my rendered page returns:
Dart Prototype
- hi there!
- 5
- Instance of 'WebService'
And the source of that page...
<!DOCTYPE html>
<!-- This file was auto-generated from web/dart_prototype.html. -->
<html><head><style>template { display: none; }</style>
<meta charset="utf-8">
<title>Dart Prototype</title>
<link rel="stylesheet" href="../dart_prototype.css">
</head>
<body>
<h1>Dart Prototype</h1>
<div id="location_management_container">
<span is="location-container"></span>
</div>
<script type="application/dart" src="dart_prototype.html_bootstrap.dart"></script><script src="../packages/browser/dart.js"></script>
</body></html>
I think my problem may be solved by using the
inserted
life cycle method instead ofcreated
.Initially when I read the
WebComponent
life cycle method description, it said:I'm still not sure if this is the right method to use, but I have the object I'm looking for - so I'm going to continue to experiment. Here's my updated
WebComponent