Using async configuration in AngularJS directive - asynchronous

I have a directive that looks at configuration to figure out what template to use. It used to work great; I had a Config service that just returned an object with config values, and then I did something like this:
if (Config.Values.ReleaseVersion < 1.0) {
template = 'partials/pagebeta.html';
}
else {
template = 'partials/page.html';
}
templateUrl: template
Recently a problem was introduced. My Config service has to get values from a json file. Now because getting config is async, I am now passing back a promise from the Config service. This is creating problems for me in my directive - I can't do this:
var template;
Config.then(function(config) {
if (config.Values.ReleaseVersion < 1.0) {
template = 'partials/pagebeta.html';
}
else {
template = 'partials/page.html';
}
});
templateUrl: template
Any suggestions are appreciated!

If your templateUrl depends on the value computed asynchronously you can't use the directive's templateUrl property anymore and you will be obliged to use lower-level API, namely $http and $compile.
Roughly what you need to do (only possible in the linking function) is to retrieve template's content using $http (don't forget to involve $templateCache!) and then compile template's content "manually".
It might sound like it is a lot of work but in practice it is rather straightforward. I would suggest having a look at the ngInclude directive sources where this pattern is used.

Related

in ASP.NET core (.NET5) how can i write logs for each request on separate files? Using Serilog or other

I'm new to .NET and to webservice development, so i'm not exactly sure how to implement the requirement i have.
My webservice gets a POST request with some data, which i need to
process to generate a pdf file: name_YYYYMMDDHHmmss.pdf.
For monitoring this i want to have a separate logfile for each request, named like the output file: name_YYYYMMDDHHmmss.log
I would like to avoid passing a config object into every class/function in which i need to add stuff to the log file
I've managed to install Serilog and it works for what i need, but not when i get concurrent requests. I'm also not exactly sure how simultaneous requests are handled in .NET (i have no thread specific code written so far), but as far as i can tell, when i change Global Logger file name, that object is shared across all threads so all of them write to the same file.
I've looked at a bunch of solutions, but i haven't managed to find nothing that suits this, and it seems most people have everything into 1 file...
Is there any clue or tips you can give me? I'm open to using something other than Serilog.
One way to have dynamic file names based on a specific context is by using the Serilog.Sinks.Map and then, via a middleware in the request pipeline, you can add a property to the log context that drives the file name to be used when writing to the log.
Examples of similar usage of Serilog.Sinks.Map to decide which file name to use at run-time:
Serilog - can not log to multiple files based on property
In Serilog dynamically changing log file path?
The best solution that I found to this problem was using Serilog.Sinks.Map. I configured my Logger something like this:
Log.Logger = new LoggerConfiguration()
.WriteTo.Map("Name", "Default", (name, wt) => {
var fileName = name == "Default" ? "log" : $"{log-{name}}"
wt.File($"./{fileName}-.txt");
}).CreateLogger();
Then on my controller, on each method where I needed this feature, I enclosed all the instructions inside a LongContext like this:
[HttpGet]
public IHttpActionResult Get() {
using (LogContext.PushProperty("Name", "theFileName") {
// ...
_myService.Method1();
// ...
}
}
public class MyService : IMyService {
// ...
public void Method1() {
// ...
Log.Information("This is what happened at this point…");
// ...
}
// ...
}
So all the Log's inside will use that context and it will write on a different file with the name you set for that context without having to modify any Log.Information/Error/Warning/etc that you already have on your code.
This is the ugly part... you have to define a context on a root place in order to make those Logs write on a different file. So for a controller method, the first thing you have to do is to enclose all with a LogContext.

Meteor: How to point a template prototype at another template?

I have a feeling that it must be possible to point to template helpers from one template to another. Does anyone know how to do this?
I see in the console that I have access to the Template I want: i.e. Template.Users_edit_page.
And it looks like there is a __helpers object with all the templates defined (Template.Users_edit_page.__helpers).
How can I do something along the lines of:
Template.User_form.prototype.helpers = Template.Users_edit_page.helpers__
and then ideally any helper called from the User_form template (which is a child of the Users_edit_page) would run the Users_edit_page template helper
While I fully encourage digging into the internals of a framework to better understand what it is doing, directly linking into implementation details like this (e.g. *.__helpers) is generally not a good idea, as framework developers may change implementation details breaking your code.
When you use the public APIs you can expect less breaking changes, and advanced notice before that happens (e.g., APIs marked for future deprecation).
As I mentioned in your other question the most flexible approach to sharing helpers across templates is with Template.registerHelper.
However if you need something more targeted you can define your functions as standalone javascript functions:
passwordSecure = function(password) {
return password.length > 8;
};
validEmail = function(email) {
return email.contains('#');
};
Then include them as helpers in all the templates you want them in like this:
Template.User_form.helpers({
'passwordSecure': passwordSecure,
'validEmail': validEmail,
});

Get data from the parent scope

Im trying to implement a single-page app with Ractive using components, and I need to have some page-wide options. I did like this:
...
data: {
options: {
someOption: true
},
...
Everything was fine while I used it like {{#if options.someOption}}, but then I faced a problem - rective.get('options.someOption') returns undefined (both with ractive.get('options')). Observing dont work as well. Is there any way to make my code understand me?
UPD. Accidentally solved problem with a portion of magic - get() starts working when I place {{options.someOption}} on template.
Ractive programmatic data access within an instance (includes components) can currently only "see" data that is:
Defined as data
Specified explicitly as a component parameter
Used as a reference in the template
For #1, you can include the options as default data and it will be available to all instances:
Ractive.default.data = {
options: {...}
}
Any new Ractive instance, including components, will have an options data property.
For #2, even if you have deeply nested components, you can have the parent of the component that needs the data include it as a parameter:
// Component somewhere in the "app" hierarchy.
// By referencing {{options}} in its template, it will find that data
// make it explicit on the widget component, which can then use it
// programmatically
<widget options='{{options}}'/>
For #3, you can include a "dummy" reference in the component template:
// by using it in the template, it is now available for programatic access
{{#with options}}{{/with}}
Of course then there's #4, enhancing Ractive to allow same lookup in code as template

Serving 'static' node pages with Meteor

I'm working on a meteor app, and as part of it it would be very nice to return some static pages containing JSON.
The JSON they return is generated by running some node (connecting to the Twitter API), however it does not reflect any underlying Meteor collection, so I don't think any of the packages that allow you to build an API on your meteor app would be appropriate.
I can see that one solution is to do this part outside of meteor, however I like the idea of only having one thing to deploy and wondered if there is a solution in meteor, possibly by making a package?
Yes, as justswim already said in the comments, I think you are looking for something like this:
Router.map(function () {
this.route('serverFile', {
path: '/posts/:user',
where: 'server',
action: function () {
var user = this.params.user
// get your data from Twitter API, e.g., using the HTTP package.
this.response.end(JSON.stringify(yourobject));
}
});
});
You can easily define a meteor API using the Meteor iron-router. Just define the route that you want to serve as the call for your api. When a user hits this route, your app will render the corresponding template (in which you can place the static json).
In your Router's map function, you might have something like this:
Router.map(function () {
/**
* The route's name is "jsonTemplate"
* The route's template is also "jsonTemplate"
* The template will be rendered at http://yourapp.com/apiEndpoint
*/
this.route('jsonTemplate', {
path: '/apiEndpoint',
template: 'jsonTemplate'
});
});

Symfony2 output any HTML controller as JSON

I have a website completed that was created in Symfony2 and I now want a lot of the features of the site to now be made available in a mobile app.
My idea is by appending a simple URL variable then it will output all the variables of the relevant page request in JSON.
So if I connect to
www.domain.com/profile/john-smith
It returns the HTML page as now.
But if I go to
www.domain.com/profile/john-smith?app
Then it returns a JSON object of name, age and other profile info.
My app code then receives the JSON and processes.
I can't see any security issues as it's just really the variables presented in JSON and no HTML.
By doing the above I can create all the app code and simply make calls to the same URL as a web page, which would return the variables in JSON and save the need for any more server-side work.
The question is: How would I do this without modifying every controller?
I can't imagine an event listener would do it? Maybe I could intercept the Response object and strip out all the HTML?
Any ideas as to the best-practice way to do this? It should be pretty easy to code, but I'm trying to get my head around the design of it.
There is a correct way to configure the routes for this task
article_show:
path: /articles/{culture}/{year}/{title}.{_format}
defaults: { _controller: AcmeDemoBundle:Article:show, _format: html }
requirements:
culture: en|fr
_format: html|rss
year: \d+
However, this would still require you to edit every Controller with additional control structures to handle that output.
To solve that problem, you can do two things.
Create json templates for each template you have, then replace html in template.html.twig with template.'.$format.'.twig. (Be careful to ensure users can't pass a parameter without validation in the url, this would be a major security risk).
Create your own abstract controller class and override the render method to check the requested format and provide output based on that.
class MyAbstractController extends Symfony\Bundle\FrameworkBundle\Controller\Controller
{
public function render($view, array $parameters = array(), Response $response = null)
{
if($this->getRequest()->getRequestFormat() == 'json')
{
return new Response(json_encode($parameters));
}
else
{
parent::render($view, $parameters, $response);
}
}
}
NOTE The above code is a prototype, don't expect it to work out of the box.
I personally would deem the second method more correct, because there is no duplication of code, and less security concern.

Resources