How can I configure webpack + aurelia to use server-side templates - razor

I'm trying to get my app to use server-side templates(.cshtml) and have tried the recommended approach of overriding the ViewLocator.prototype.convertOriginToViewUrl.
Unfortunately it doesn't seem to work with webpack, as hinted by #EisenbergEffect. on my previous question
I have a route that returns html and I want to use that as my view.
Example here in ASP.NET MVC
public ActionResult Template(string view)
{
return View(string.Format("~/Views/Shared/ClientTemplates/{0}.cshtml", view));
}
Aurelia code
import {ViewLocator} from 'aurelia-framework';
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging();
ViewLocator.prototype.convertOriginToViewUrl = (origin) => {
return "/common/template?view=" + origin.moduleId;
};
aurelia.start().then(a => a.setRoot());
}
Result Error: Cannot find module './/common/template?view=app'.
Running the route /common/template?view=app in a browser returns, as expected, the markup that resides in the app.cshtml
How can I configure webpack + aurelia to use server-side templates?

Related

Typescript return HTML Template Element from Constructor typing not working

It is 'illegal' to use new when creating an instance of Template, where Template extends an HTMLTemplateElement.
To overcome this limitation, I get and return an HTMLTemplateElement using document.getElementById(id) from the Template constructor as below:
export class Template {
private htmlTemplateElement: HTMLTemplateElement;
constructor(id: string) {
this.htmlTemplateElement = document.getElementById(id) as HTMLTemplateElement;
return Object.assign(this.htmlTemplateElement, this)
}
public test = () => this.htmlTemplateElement.innerHTML
}
Providing an HTML Template Element exist in the DOM,
I can create a new instance of Template and use the extension method test() as illustrated below:
const template = new Template(id)
console.log(template.test())
console.log(template.innerHTML)
Both console.log() works just fine and prints the correct text to the console.
HOWEVER, the typescript compiler complains about template.innerHTML.
The error I get, saying innerHTML does not exist on type Template
Question: How can I add type information so I do not get a compiler error?
I have tried to use export class Template extends HTMLTemplateElement.
That does not work since it is illegal to create an instance using new.
I love typescript, but sometimes the type checking gets in my way.
Help me out here, please.
Although not ideal, I was able to keep the typescript compiler happy by implementing the following interface:
export interface ITemplate {
[key:string]: any;
test(): string;
}
and then using the interface:
export Template implements ITemplate {
...
}
Note:
Why did I not use customElements.define(<tag-name>,Template)?
I do not intend to create a new custom instance of HTMLTemplateElement, I just want to return an existing HTMLTemplateElement with additional utility extension methods.
Also, It might very well be possible that my approach is completely wrong.
However, that is a different topic than the question asked here.

Spring + AngularJS (HTML) getting Context Path?

I am currently using Spring and AngularJS.
So far no problem displaying my index.html using Spring like so
#RequestMapping(value="/")
public String index() {
return "/app/index.html";
}
Is there any way I can get my context path in my .html? Or should I render my index as index.jsp?
As you said, you should render it as a JSP in order to access the contextpath:
${pageContext.request.contextPath}
If you wanna stick to pure HTML maybe you could extract it from the URL with Javascript:
function getContextPath() {
return window.location.pathname.substring(0, window.location.pathname.indexOf("/",2));
}
console.log(getContextPath());

Where to load the server data

I'm using the react-router and navigate to a component that gets an ID in the URL and has to use this ID to get data from the server with the help of an action.
At the moment I'm calling the action creator in the componentWillMount hook.
This works so far, but brings a problem.
In the render method I have to check, if myData really exists with all its attributes, before I can really render.
#connect(state => {myData: state.etc.myData})
export default class extends React.Component {
componentWillMount = () => {
this.props.dispatch(
ActionCreators.getData(this.props.params.id)
)
}
render() {
if (this.props.myData.hasNotLoaded) return <br/>
...
}
}
Is there another way to get data into the store before rendering without manual checks?
You can subscribe to router's onEnter hook and dispatch actions from where.
const store = configureStore()
const routing = (<Router>
<IndexRoute onEnter={()=>store.dispatch(myLoadDataActionCreator())}/>
</Router>)
So you can avoid setState from previous answer and don't tie up component with redux.
You should create a call back, for example:
_onChange() {
this.setState(myStore.getData());
}
Then in the following react functions do the following:
componentDidMount() {
myStore.addChangeListener(this._onChange);
},
componentWillUnmount() {
myStore.removeChangeListener(this._onChange);
}
I assume you're using the mixins for the react-router, if not, take a look at the docs for it, they have some useful functions that are worth looking at.
I don't think you will need that if logic in the render() method, react will handle that with the virtual dom management and know when to load it and the data.

Laravel 3: Class not found in namespace

This is the problem: I haven't be able to load a class from a namespace.
I'm developing a restful app and I'm trying to follow the Entity/Service/Repository way to access and give format to the requested data. The thing is that I cannot load any class from Services. I have created a folder inside my app called api, and within it the others 3 folders: api/entities/, api/services/ and api/repositories/. There are 2 more folders inside services: validators and datapickers.
As it is a RESTulf app, I also created an api folder inside the controllers folde: controllers/api/.
Here is the the current tree of my app folder:
app/
api/
entities/
repositories/
services/
datapickers/
MemberData.php
ConsumeData.php
validators/
...
models/
controllers/
api/
members.php
(other restful controllers)
languages/
...
In first instance, this is my Autoload section from start.php:
Autoloader::directories(array(
path('app').'models',
path('app').'libraries',
path('app').'api'
));
Autoloader::namespaces(array(
'Api' => path('app').'api',
));
And this is MemberData.php:
<?php
namespace Api\Services\Datapickers;
use Api\Repositories as Repo;
class MemberData
{
/* Do some stuff */
}
Now, when I try to use MemberData in controllers/api/members.php:
<?php
use Api\Services\Datapickers\MemberData;
class Api_Members_Controller extends Api_Base_Controller
{
public function get_index($id = null)
{
if (!empty($id))
$this->params->data = MemberData::getById($id);
else
{
$this->params->data = MemberData::getAll(
Input::get('offset'),
Input::get('limit')
);
}
return Response::json($this->params, 200);
}
}
I get the following:
Unhandled Exception
Message:
Class 'Api\Services\Datapickers\MemberData' not found
Location:
/path_to_project/application/controllers/api/members.php on line 15
which is this line: $this->params->data = MemberData::getById($id);
I autoload the api folder and register the base api namespace in start.php but I still keep receiving the same error. IT's like Laravel doesn't recognize the api namespace or something like that.
I tried to register the full namespace:
Autoloader::namespaces(array(
'Api\Services\Datapickers' => path('app').'api/services/datapickers',
));
but the error I got was: Call to undefinde method 'Api\Services\Datapickers\MemberData::getById()'. This was just a test (I don't want to register every sub-namespace in the Autoloader).

Razor.ServiceStack - Views not rendering, just default "Snapshot"

I've setup a site using http://razor.servicestack.net/.
I've created several views and matching services with an example as follows:
Service Example:
using ServiceStack.ServiceHost;
using ServiceStack.ServiceInterface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace website
{
[DefaultView("AboutUs")]
public class AboutUsService : Service
{
public object Get(AboutUsRequest request)
{
return new AboutUsResponse
{
//any properties that need to be set on the response object can be done inline here
};
}
}
[Route("/About-Us")]
public class AboutUsRequest
{
//any request parameters we need can be provided here. They should be auto parsed from the request
}
public class AboutUsResponse
{
//any response properties we want to use in the view can be defined here
}
}
View Example (located at /Views/AboutUs.cshtml)
#inherits ServiceStack.Razor.ViewPage<website.AboutUsResponse>
<html><body><h1>About Us</h1></body></html>
This loads fine on windows, but fails to load on Mono/NginxFastCGI, and instead just shows the default API snapshot page:
Snapshot of AboutUsRequest generated by ServiceStack on 11/17/2012 02:30:14
view json datasource from original url: http://dev.mydomain.com:80/About-Us? in other formats: json xml csv jsv
Is there some specific change that I need to configure for this to work on the Mono/Linux side? By the way, i have IOMAP=all already turned on.
Any ideas on how to get this working would be greatly appreciated!
Unfortunately you left out the most important part: the name and location of the Razor view.
The Snaphot page is a fallback for when ServiceStack can't find the view it's looking for, in this case since you've specified [DefaultView("AboutUs")], ServiceStack will look for a view named "AboutUs.cshtml" in the /Views/ directory, is that what you have?