Unlike onMount there is no beforeMount lifecycle event in SvelteJS. So, how do we fetch data that the page depends on before mounting? onMount fetches produces glitches. One can say that I can wrap dependent DOM inside if conditions. But I don't think it is the right solution. Very like in Sapper there is a preload function that can load page dependent data before mounting. What is the alternative to this (Sapper's preload) behavior in SvelteJS?
You'd create another component that doesn't render the Component until the data is ready.
<script>
import Post from "./Post.svelte";
const url = 'https://jsonplaceholder.typicode.com/posts/1';
const promise = fetch(url).then(response => response.json());
</script>
{#await promise then data}
<Post title={data.title} />
{/await}
REPL
Depending on the scenario you can use a router that has data loading supports, like the sveltekit router.
You can put the fetch code right under <script> tag
A <script> block contains JavaScript that runs when a component instance is created.
There is also context="module" attribute with <script> tag. It
runs once when the module first evaluates, rather than for each component instance
See the official docs
Noob here, to your sub-question: isnt svelte front end only? Meaning no SSR support and thus no option for preloading data with first user request.
Since, you dont have any server that would preload your data and give the user prepacked front-end (svelte pages) with data. Thus, you need sapper to provide a functionality where server can fetch data with first user request, populate front end and send it to user.. This way, user receives svelte pages, populated with data, upon first response from your server.
Since you use only svelte, user needs to contact your server more often.. First, it fetches the front-end, then front-end fetches data from back-end. Furthermore, it aint SEO friendly as robots dont wait for the subsequent server responses. Thus, your pages wont be analyzed properly as robots analyze 'blank'page, no data mounted yet, and move to next, before response can be processed.
Please, correct me If I am wrong ;)
I believe above answer is right:
1. create empty variable in script tag
2. add below onMount call and fetch data from serverto above declared variable
3. check if var is empty and show loading button
4. if var isnt empty, then show user content
6. profit?
P.S: Sorry for any misconceptions or bad English :)
Related
I am new to VueJS.
Let's assume that I plan to create an extensive application. And for example I have 3 separate pages: mypage.com/account, mypage.com/players, mypage.com/orders. Each page has its own controller and in it I return a file with a view (account.blade.php etc.) and pass parameters in variables. Then in each of them I would like to use Vue. And here I have a few questions:
1) Do I need to create separate app.js files for each page with a Vue instance in the / resources / js / folder? Something like:
app-account.js
const app-account = new Vue({
el: '#app-account ',
});
app-players.js
const app-players= new Vue({
el: '#app-players',
});
etc.?
If not - how to do it? Declare all components in one app.js file? And is this correct? Because then when you enter mypage.com/account in the app.js file in / public / js / all other Vue components are stored. So the actual component is displayed on the page and all components are downloaded on the page.
2) Why does every component have to be the default?
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
3) How to use Laravel + Vue correctly when you do not want the site to be SPA?
4) Is it correct that all data is transmitted along with the view? Is it better to create controllers only for displaying the view and download data via Vue from api?
5) What about the features from the Blade template system?
I could display a link to the route in them via {{route ('name')}}. The only way to achieve this in Vue is to pass a parameter to the component? Is this the correct way?
<example-component routeToXXX="{{route ('name')}}" />
Welcome to Vue world.
Since Laravel/PHP at navigation between pages leads browser to rerender DOM, its your choice if you separate app files or just write inline js wrapped with <script> (if you do that ensure vuejs is loaded before your script/defered). In case you want to keep Laravel your core, you may also consider diving into livewire, alternatively you have to explore what the world is trying like: VUE2 component register in Laravel
It's a Javacsript syntax, basically SFC (Single File Components) are supposed to export JS data/object/functions which can be used or loaded, Vue has a clear documentation, try it. Learning Vue, makes you learn JS (suggestion: consider learning the basics, start by understanding difference between sync, async, loops, data types, functions, function functions).
There's no concrete way that you have to follow in order to achieve what you need or accomplish certain task. In any case if your needs are met by your solution at your stage of career, that might be the correct way. Just keep trying and outcome your abilities by time (reviewing other's code/libraries helps).
This is matter of choice, SSR (ServerSideRendering) is commonly used in cases you do not want to expose the logic in the frontend or have security concerns. There are also scenarios where you perform API calls to enhance overall performance like pagination or filters. However your data publicity/privacy always depends on how you authenticate users, each API call must ask for a valid access token that will ensure the backend, that credentials are met to reach the data. With experience in frontend you'll be convinced which are the best practices.
Laravel has a blade helper to ignore templating engine (#verbatim,#endverbatim and others). Passing data to your Vue part if its inline script you may open php tags like within your #verbatim section. In other cases if you already know what you are about to pass your JS, you can define a global variable somewhere in between your blade view like <script> var globalVar = { url1: "<?= route('name'); ?>", url2: "<?= route('name2'); ?>" } </script> or you can echo out encoded json so it renders the JS variable like var globalVar = <?= json_encode($yourVariable); ?>;
Finally PHP and JS are both two different worlds, aiming towards a similar syntax. It's a big decision to consider loose coupling API and View logic, but it might pay well in long term.
I have a listing page for an e-commerce website with various items (item_list.php). This page is generated with a PHP loop and displays each item inside a <li> element. Every item is a link to the same page, called item_details.php .
When clicking on the link i want to run a script that changes a SESSION var to a certain $id (which will be excracted from the <li> itself with .innerHTML function) and then allowing the browser to move into the next page (item_details).
This is needed so i can display the proper information about each item.
I think this is possible with Ajax but I would prefer a solution that uses JS and PHP only.
(P.S.This is for a University project and im still a PHP newbie, i tried searching for an answer for a good while but couldn't find a solution)
No JS or other client-side code can set session values, so you need either an ajax call to php, or some workaround. This is not a complete answer, but something to get you thinking and hopefully going on the project again.
The obvious answer is just include it in the link and then get it in PHP from the $_GET -array, and filter it properly.
item title
If, however, there is some reason this is not a question with an obvious answer:
1.) Closest what you're after can be achieved with a callback and an ajax call. The idea is to have the actual link with a click function, returning false so the link doesn't fire at once, which also calls an ajax post request which finally will use document.location to redirect your browser.
I strongly advice against this, as this will prevent ctrl-clicks causing a flawed user experience.
Check out some code an examples here, which you could modify. You will also need an ajax.php file which will actually set the session value. https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#product-click
2.) Now, a perhaps slightly better approach, if you truly need to do this client-side could be to use an click handler which instead of performing an ajax call or setting session directly, would be to use jQuery to set a cookie and then access this data on the item_list.php -page.
See more information and instructions here: https://www.electrictoolbox.com/jquery-cookies/
<script>
$('product_li a).click(function(){
$.cookie("li_click_data", $(this).parent().innerhtml());
return true;
});
</script>
......
<li class="product_li">your product title</li>
And in your target php file you check for the cookie. Remember, that this cookie can be set to anything, so never ever trust user data. Test and filter it in order to make sure your code is not compromised. I don't know what you want to do with this data.
$_COOKIE['li_click_data'];
3.) Finally, as the best approach, you should look at your current code, and see if there is something you can re-engineer. Here's a quick example.
You could do the following in php to save an array of the values in the session on each page load, and then get that value provided you have some kind of id or other usable identifier for your items:
// for list_items.php
foreach($item as $i) {
// Do what you normally do, but also set an array in the session.
// Presuming you have an id or some other means (here as item_id), to identify
// an item, then you can also access this array on the item_details -page.
$_SESSION['mystic_item_data_array'][$i['item_id]] = $i['thedata'];
}
// For item_details.php
$item_id = // whatever means you use to identify items, get that id.
$data_you_need = $_SESSION['mystic_item_data_array'][$item_id];
Finally.
All above ways are usable for small data like previous page, filters, keys and similar.
Basically, 1 and 2 (client-side) should only be used, if the data is actually generated client-side. If you have it in PHP already, then process it in php as well.
If your intention is to store actual html, then just regenerate that again on the other page and use one of the above ways to store the small data in case you need that.
I hope this gets you going and at least thinking of how to solve your project. Good luck!
Sorry if the question is confusing but I am just getting started with React. Basically, I am looking to start adding individual components to an existing website. Currently, when the page loads there are a couple of AJAX requests that update different parts of the page with jQuery.
For example, I make an AJAX request that is called every 30 seconds to get AccountInfo and when it returns a response, I update two separate parts of the page, let's call them AccountPanel and SideBar.
Question #1
If I were to create a component for the AccountPanel, should I make the AJAX request when the component mounts and continue to use jQuery to update the SideBar in there?
Question #2
Or is it better to create components for both and pass the AJAX response as props?
ReactDOM.render(<AccountPanel />, document.getElementById('accountPanel'));
ReactDOM.render(<SideBar />, document.getElementById('sideBar'));
Any help is appreciated :)
Actually, I think you need some state container. To share state(in your case AccountInfo) between all of your components.
Personally, I recommend using Redux. Because this container is completely predictable.
In result you code will looks like:
//create redux store somehow
ReactDOM.render(<AccountPanel store = {resuxStore}/>, document.getElementById('accountPanel'));
ReactDOM.render(<SideBar store = {resuxStore}/>, document.getElementById('sideBar'));
In Sails.js, a route is set up against a controller method which can render a view. For the most part, this is straightforward, i.e. you could set up a GET /users route that points to UserController.find (which is usually set up automatically anyway).
However, say the home page of a blog renders the 10 most recent posts in the main section and a column with a list of authors and categories. The controller method has to fetch posts, authors, and categories before rendering the view and sending it back to the client. Clearly, a method like this doesn't really belong in PostController, AuthorController, or CategoryController.
What's the best thing to do in this situation? Create a controller for rendering views that rely on data from multiple models? Is there a good name for such a controller?
Thanks!
What I would do (this is purely opinion-based) is creating a PageController and create an action for each page you'd want.
For your home page example you can create a home action, get whatever you need and then render it with res.ok() (if everything is fine).
Another option would be to use Sails as a pure API and use HTTP requests (Ajax) or sockets to get your data in JSON. If you want to do so, I'd advise you to use a front end framework such as Angular, Ember, React...
By the way you could also create actions rendering HTML in your existing controllers and create a route to hit them through Ajax requests and just print them in your page. I'd prefer the 2nd solution because it takes full advantage of the Blueprint API (you don't need new controller or action whatsoever).
As Yann pointed out, this answer has to be a little opinionated. It seems that you are using the views system and not building a single page application. For the home page, I would go for an IndexController.js file with a home(req, res) action.
// api/controllers/IndexController.js
module.exports = {
home: function (req, res) {
// Retrieve all the information you need
// Take care about managing the asynchronous calls before rendering the view
return res.view('homepage');
}
};
Declare the route
// config/routes.js
module.exports.routes = {
'get /': 'IndexController.home'
}
Create the view in views/homepage.ejs.
I have read a lot of answers relating to how to dynamically add forms to an model formset in Django and can successfully implement that. However, I would now like to submit the formset with AJAX. This is mostly working now but I have an issue that I can't find a solution to in any other answer:
If you dynamically add a form to the formset, you give it a new form id number that is one larger than the maximum the form currently has and you also increment the management TOTAL_FORMS count by one. The newly added form then saves successfully as a new object.
I am trying to submit by AJAX so the user can continue editing without having the page refresh. The formset saves fine but any dynamically added forms are now existing objects. To account for this I need to increment the INITIAL_FORMS count on the management form when the save is successful. Easy enough. However, I've also realised I need to give the newly created objects an ID since they now exist in the database.
How can I get my view to tell me the ID of the new objects in its response to the AJAX call? Or is there a better way of looking at this?
Django forms and formsets are intended for classic browser-based posting of data. Though they can definitely be made to work with Javascript, the more you want to part from the normal behavior, the more complex it gets.
Depending on your requirements, you might start thinking about dropping it and switch to Javascript + REST endpoint. Of course, if you need progressive enhancements and you are required to have it work without javascript, that's not an option.
In any case, you want to have a customized view for posting from JS, so that you can get the result back and parse it easily in your AJAX handler. Probably some JSON.
There are several approaches you could take.
Have your AJAX send data to a different URL. This is pertinent if you have an API or are planning to build one at some point. So your form, when submitted normally, will do its old-style processing but your AJAX will talk to the API endpoint instead.
For instance, your form send to https://example.com/myform, but your Javascript code talks to REST api at https://example.com/api/v1/mymodel/ (sending PUT, POST and DELETE requests as appropriate).
Or if you don't have an API and building one seems overkill, you may just alter your view so it formats its output differently depending on whether the data is being submitted in the regular way or using AJAX.
You'd go about it like this:
class MyFormView(.....):
def render_to_response(self, context, **kwargs):
if self.request.is_ajax():
return self.render_to_json(context, **kwargs)
return super().render_to_response(context, **kwargs)
def render_to_json(context, **kwargs):
data = {
# see below!
}
return HttpResponse(
content=json.dumps(data).encode('ascii'),
content_type='application/json',
)
This is just an outline. You need to ensure is_ajax will detect it properly (see django doc). And you need to properly build data from context: extract the things you want to send back to your JS code and put them in the dict.
You will find it's manageable if you just do this for one, maybe two views in your project, but very quickly you'll want to have a small API instead, especially given how easy it is to build one with packages such as Django REST framework.
In your view, where you save the object, AFTER the save, the object.id will contain the new id for the object, which you can return via json or however you want in your ajax response, and then yes you will need to fill that into the formset row so that it will be submitted the next time.
One thing you have to watch out for is that django expects all existing rows to be at the top of the formset, and any new rows to be at the bottom. Otherwise, the formset save will complain about missing id's. So if you're doing any kind of sorting in your javascript, you can't do that.. unless you do quite a bit of fixing of all the field names etc in the formset. The formset code uses the numbers in the management form to determine which rows to insert and which rows to update, it does not do it on the basis of whether or not an id is present. Unfortunately...