i'm developing a webapp in AngularJS (1.5) and Flask, and i'm self-taught.
My webapplication is not public, so any resource is reserved.
In the first version i manage rendering of the pages by AngularJS through ngRoute and resolve, but i've understood that is a mistake.
In the second version i'm changing the rendering of the page from Angular to Flask, but every time i've the same problem: Flask render a page, send it to Angular but Angular doesn't show it but instead it show the template in the routing. I've try many cases:
render the login page with Angular and serve just a controller to call the server and load the server rendered page;
render all with Flask and just a controller in Angular to manage the auth
use the resolve instead a function in controller for manage the reserved page
For each case i've the same situation: server response with html rendered page, but it's not showed by Angular.
I've found some solutions about my problems: upgrade to Angular2.0 or implement Node.JS, or implement angular-server ... but i would like to avoid to add other components and understand what's wrong.
Part of the Angular routing code
var reserved = {
name: "reserved",
params: {aaa:true} }
var reservedContent = {
name: "reserved.content",
url: "/reserved",
template: "<h1>Angular rendered</h1>" }
and in app.run
$transitions.onBefore({ to: 'reserved.*' }, function(t){
var AuthService = t.injector().get('appAuth');
var authorization = appAuth.authorization(t.to().url.substr(1), $rootScope.token);
authorization.then(function() {
$rootScope.resource = t.to().url;
pySrv.app($rootScope.resource)
.then(function(data){
console.log("The html server rendered page: " + data);
console.log("The Angular template in state" + t.to().template);
t.to().template = data;
},
function(data){
console.log("Reject"); } );
},
function(){
$state.target("403"); }); });
I always see "Angular rendered" in the page.
Related
I am wondering, what would be the best setup of data flow from PHP (database) to fronted Javascript rendering, lets say VueJS.
My first idea is, that will provide data attribute with JSON data to HTML element - div, which Vue instance will be mounted on.
I dont want to create REST API and load data via AJAX HTTP requests from Vue.
# PHP part
echo '<div id="myId" data-my-data="{h1:\"My heading\"}"></div>';
// Javascript part
import Vue from 'vue/dist/vue.js';
import App from './MyApp.vue';
const el = document.querySelector('#myId');
new Vue({
el,
render: h => h(App, {
props: {
myData: JSON.parse(el.dataset.myData),
},
}),
});
What do you think, is it ok or is there any other option except REST?
Update:
Main purpose is that my App will handle complex - multi-step Forms with some complex fields, which I would like to create as reusable components.
App will validate forms via AJAX (to prevent re-rendering page), on success redirect to success page.
My infrastructure would be, that PHP will prepare data, render main layout with assets (JS + CSS) and DIV with data atributes for Vue App.
So far I've been building Laravel and Django apps that return views or templates from backend. So far so good.
However, I'm now building a Laravel API that gets called from a frontend AMP code.
In the old ways I do this in Laravel:
From web.php
Route::get('/', function () {
return view('welcome');
});
Or I can return the view from the controller.
However, if the Laravel app is an API that returns JSON, how can I design URLs?
Basically, if someone clicks a link on the homepage that should take hime to a user profile, say:
/user/{id}
Where will I decide how this URL looks like and which endpoint to call?
You can use the same route syntax, but instead of returning a view, you return a json response.
Route::get('api/user', function () {
$data = ['status' => 'success', 'data' => 'stuff'];
return response()->json($data);
});
Take a look at the response documentation for all available types of responses.
I finally wrapped my head around this. At least I think so.
in web.php I have a set of Closures with the URLs that I want. These Closures return views with no data. Similar to this:
Route::get('/', function () {
return view('welcome');
});
And then in the view I call the API endpoints as specified in api.php to render the data that I need in the view.
// List activities
Route::get('activities', 'ActivityController#index');
Laravel 5.3 and above provides the seperate route file routes/api.php, where you can write all routes related to your api requests.
for controller just create a seperate folder in controller folder named as 'Api' and create api related controller in that.
and from there you can write function for corresponding routes. and return json as
return response()->json(['data'=>$data]);
Or you can use https://github.com/nWidart/laravel-modules package to create a sepperate api module in laravel.
Am playing with Framework7 to do hybrid mobile app development. I have three tabs (bottom fixed), which are Home, Contacts and Settings/Profile
My app.js file looks somewhat like this:
var $$ = Dom7;
var app = new Framework7({
//.....
data: function () {
return {
user_profile : ''
}
},
on: {
tabShow( tab ) //-- when a bottom tab is clicked
{
if( $$(tab).attr('id') == 'view-settings' )
{
//.. do ajax call and get the response data in "resp"
app.data.user_profile = resp.response.profile; //setting the info to app's data
}
}
},
routes: routes
});
var settingsView = app.views.create('#view-settings', {
url: '/settings/'
});
And in routes.js:
routes = [
{
path: '/',
url: './index.html',
},
{
path: '/contacts/',
componentUrl: './pages/contacts.html',
},
{
path: '/settings/',
componentUrl: './pages/settings.html',
}
];
This Contacts page contains static content. For the Home page, am doing the AJAX API call during the deviceready state. Because am setting up some headers for authentication and stuff(for all the AJAX api calls) in there.
The problem am facing is, am unable to display the content in Settings page. It is always empty!
Am using this in that template page:
<div class="item-title item-label">Full Name - {{$root.user_profile.full_name}}</div>
I want to compile that template only when clicking the respective tab button.
Maybe that's the problem.
Any suggestions?
After going through the documentations again and again, I got another way to do this.
So, during the tabShow event, I check whether the user is accessing the Settings/Profile tab. If so, I check whether an object in app.data (eg: app.data.user_profile is empty or not(am storing the profile details there). If empty, I would do an AJAX API call to get the profile details. When the profile details is obtained, I would use app.form.fillFromData() method to fill the form. Documentation here: https://framework7.io/docs/form.html#form-data-app-methods
Make sure to name the form as well as the input elements in that form, and the same name should be use in the object(key name) when calling the fillFromData() function.
And one more thing, for the routes, /settings/ path, I used url instead of the componentUrl property to pass the url of the page.
This may not be the best solution, but am still learning. And it seems to have solved by current problem.
Thank you
in Angularjs in a html page I need to load an external javascript file:
<script src="https://www.my-url.com/js/my.js?Key=xxxxxxxx"></script>
But based on different env (test, beta, prod), I will have different Key.
How can I implement this like what we usually do using web.config in .net?
Edit:
I saw some answers, but seems not exactly what I need. so I elaborate my environment: I have a client side which is pure html and Angularjs, my server side is an Asp.net Web API web service. When I talk about web.config in the original post, I don't mean put the key in web.config, but something conceptually similar. I want this "config file" on the client side, not on my Web API.
You can use gulp-replace and automate it on your build time.
There are two issues to solve:
Getting web.config values into the angular app
Making use of the config to download a script
1. Getting web.config to the app:
I've detailed in a blog post the method I use. Essentially, use a custom angular provider in the applications .cshtml file. This will load all web.config items with the prefix of client:...
Used by the MVC controller:
public static class ApplicationConfiguration
{
private const string ClientAppSettingPrefix = "client:";
public static object GetClientConfiguration()
{
var clientConfiguration = new ExpandoObject() as IDictionary<string, Object>;
// Find all appSetting entries prefixed with "client:"
foreach (var key in ConfigurationManager.AppSettings.AllKeys.Where(key => key.StartsWith(ClientAppSettingPrefix)))
{
// Remove the "client:" prefix before adding to clientConfiguration
clientConfiguration.Add(key.Replace(ClientAppSettingPrefix, String.Empty), ConfigurationManager.AppSettings[key]);
}
return clientConfiguration;
}
}
Script added into the app's .cshtml file:
<!-- Inject the configuration -->
<script type="text/javascript">
(function() {
angular.module('client.config', [])
.provider('applicationConfiguration', function() {
var config = #Html.Raw(JsonConvert.SerializeObject(Model, new JsonSerializerSettings {ContractResolver = new CamelCasePropertyNamesContractResolver()}));
return {
config: config,
$get: function() {
return config;
}
};
});
})();
</script>
So now you can use it in you add as a normal dependency:
angular.module('app', [
// Add as a dependent module
'client.config'
])
.config([
'applicationConfigurationProvider', 'dataServiceProvider', function(applicationConfigurationProvider, dataServiceProvider) {
// Set the api root server configuration
dataServiceProvider.setApiRootUrl(applicationConfigurationProvider.config.apiRoot);
}
]);
2. Making use of config to download script
As suggested in other answers, use JQuery's getScript() function.
Other SO answers also suggest using a simple injection into the head if you don't want to depend on Jquery. Take a look at Single page application - load js file dynamically based on partial view for ideas
You have couple of options here.
Option 1:
Use Angular's http service to get script files dynamically as String and then use eval() function to execute resulting String.
References: eval Angular $http service
Option 2:
Use JQuery's getScript method
Example:
var keys={ 'prod':'prodKey',
'staging:='stagingKey',
'dev':'devKey'
}
//Assuming you have an variable storing modes like prod, staging or dev
var url='https://www.my-url.com/js/my.js?Key='+keys[ENVT.MODE];
$.getScript( url, function( data, textStatus, jqxhr ) {
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Script loaded successfully" );
});
Reference: getScript
I did the comments tutorial on http://reactjs.net/getting-started/tutorial.html and got it to render server side using .net mvc.
I have an existing mvc app where I rewrote a page in react. I'm trying to render it server side using .net but I get an error when it tries to render server side.
Exception Details: React.Exceptions.ReactServerRenderingException: Error while rendering "TopicAnswers" to "react1": TypeError: undefined is not a function
at React.createClass.render (Script Document [8]:80:39) -> var answerNodes = this.props.data.map(function(answer){
at ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (Script Document [2]:7395:34)
Here's the code:
In my MVC view:
#Html.React("TopicAnswers", new
{
initialAnswers = Model,
url = Url.Action("TopicAnswers", new { id = ViewBag.TopicID }),
})
My TopicAnswers.jsx file:
var TopicAnswers = React.createClass({
getInitialState: function(){
alert('inside getInitialState: ' + this.props.initialAnswers);
return {answers: this.props.initialAnswers};
}
My ReactConfig.cs file:
ReactSiteConfiguration.Configuration
.AddScript("~/Scripts/internal/eusVote/TopicAnswers.jsx");
QUESTION: Why is it having a problem rendering the react file server side?
I got this error message trying to render React jsx file server side using .net:
"React.Exceptions.ReactServerRenderingException: Error while rendering "TopicAnswers" to "react1": TypeError: undefined is not a function"
My problem was that in the JSX file, I still had ComponentWillMount which called the loadAnswersFromServer. This is what you need if you are rendering client side. But once you adjust your code to render server side, you need to comment out/remove the ComponentWillMount so that it doesn't try to run the loadAnswersFromServer function on the server side.
With MVC, the data should be passed from the controller to the view and referenced in the #Html.Render("Comment", new { initialData = Model }) for the initial load.
Also, don't forget to comment out/remove the React.render( ... ) line from the JSX file.
alert is available only in browser window context. When rendering it on a server you can not call any functions that are browser related. If you are calling them, then you need to shim them so they are not failing on a server.