Angular 6 String interpolation not updating DOM whereas innerHTML does - angular6

I have events page and event detail page.
When I place <h1>{{ Eventinfo.EventTitle }}</h1> to display title, the DOM does not get updated with new title. However, when I use <h1 [innerHTML]="Eventinfo.EventTitle"></h1>, I do get the update title in H1 tag.
Why do string interpolation <h1>{{ Eventinfo.EventTitle }}</h1> does not work?

try console in this function and reply with whatever data you are getting in console
public getEventInfo(id)
{
this.apiService.getEventInfo(id).subscribe((data : any) => {
this.Eventinfo = data.events.results[0];
});
console.log(this.Eventinfo); //view data in console
}

Related

Better way to return gutenberg block data from Wordpress post as json - Headless Wordpress Vue

I am currently testing out Headless Wordpress with Vue. Right now I am trying to accomplish to return page content with all gutenberg blocks(Advanced Custom Fields etc).
For this I am using wp-json/wp/v2/pages api to return all pages.
Problem was that this api didn't return content with gutenberg blocks so I decided to use plugin called "REST API blocks". With this I managed to get gutenberg blocks data inside page content.
Is there a way to return gutenberg data inside content without plugin? I wouldn't want to rely on plugin especially when it's outdated.
My code
<template>
<div>
<div v-for="page in pages" v-bind:key="page.id">
<h2>{{ page.title.rendered }}</h2>
//loop trough all gutenberg blocks inside page
<div v-for="block in page.blocks">
//page content as html.
<div v-html="block.attrs.content"></div>
//acf block data. Get field named title
{{ block.attrs.data?.title }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
pages: [],
};
},
methods: {
async getData() {
try {
let response = await fetch("http://localhost:8000/wp-json/wp/v2/pages");
this.pages = await response.json();
console.log(response);
} catch (error) {
console.log(error);
}
},
},
created() {
this.getData();
},
};
</script>
My json looks like this https://justpaste.it/b43wy
This may not be the most correct way to implement Headless Wordpress with Vue but I am just doing it for learning puropouses.
Any information about Headless Wordpress is very welcome and I am up for discussion and new knowledge.

How to dynamically append HTML element to component in Vue.js

I'm new to vue.js, before this i'm using jquery or js for my project, i'm working on a project that require me to append HTML element dynamically on button click, and at the same time bind the input value to model, similar to:
$(".button").click(function() {
$("#target").append("<input type='hidden' name='data' v-model='inputModel' value='1'/>");
});
But i need this in Vue.js ways.
Here is my code:
data() {
return {
programmeBanner: [],
dropzoneOptions: {
...
...
init: function () {
this.on("success", function(file, response) {
file.previewElement.id = response;
// this is the part that i want to append the html input into
// the .dz-preview is the target that i want to append
$(".dz-preview[id='"+response+"']").append("<input type='hidden' name='"+fileInputName+"[]' v-model='programmeBanner' class='"+fileInputName+"' value='"+response+"'/>");
});
},
...
Here is a sample that i want to achieve, this is in Jquery, i need it in Vue.js
https://jsfiddle.net/041xnfzu/
Hmm I think you're mixing all kinds of code here :)
First off, you shouldn't use jquery inside VueJS. I think that your setup is a little off. You shouldn't define a whole object with functions and event listeners in your vue data object.
That's what Vue components are for, define methods in your methods property and data in you data property.
Thanks to your jsfiddle example, I have this pure vuejs example for you on codepen: https://codepen.io/bergur/pen/vwRJVx
VueJS code:
new Vue({
el: '#demo',
name: 'Adding html',
data() {
return {
inputs: []
}
},
methods: {
addInput() {
this.inputs.push(this.inputs.length+1)
}
},
computed: {
buttonText() {
return this.showInput ? 'Hide input' : 'Show input'
}
}
})
HTML template
<div id="demo">
<button #click="addInput">Add input</button>
<div v-for="(input, index) in inputs">
<input name="data" v-model="inputs[index]" />
</div>
<p>
First value: {{ inputs[0] }}<br />
Second value: {{ inputs[1] }}
</p>
</div>
Here's a walkthrough of the code.
We create a data property called inputs, that is an array.
We create a method called addInput and all that does is to push a new item into the inputs array
In the template we loop with v-for through our inputs array and render a input for each item in our inputs data property.
We then use v-model to bind each input to its corresponding place in the inputs array.
You can try to change the input value and see that the template updates the value.
So input[0] holds the value for the first input, input[1] holds the value for the second input and so on.
If you want only one element to be appended to component, then you should use v-if
https://v2.vuejs.org/v2/guide/conditional.html#v-if
If you want to append multiple elements, like todo list, you should use v-for
https://v2.vuejs.org/v2/guide/#Conditionals-and-Loops

Using Ajax in django template to update an element

So I have a button that is suppose to "Add" an "Item" to a list and update the list on the same page without refreshing it.
Adding the Item without redirecting worked. but the element is not refreshed properly
Here is my script:
<div id="list">
{% for item in items %}
{{ item.name }}
{% endfor %}
</div>
<button id="add" type="submit">+</button>
<script>
$('#add').click(function () {
$.get('/url/page/', function (data) {
$('#list').html(data);
});
});
</script>
views.py
def add_to_list(request, item_id, list_id):
item, created = List.objects.get_or_create(list_id=list_id,
item_id=item_id)
return HttpResponse(request)
I feel like I have to add something in the views? and maybe use json code?
You should append the result of your request to the div element. Try this:
$('#add').click(function () {
$.get('/url/page/', function (data) {
$('#list').append(data);
});
});
Assuming that data that you receive from GET request is not an object but just a string. If it is an object add data.name:
$('#list').append(data.name)
Hope it helps.

AngularJS increment confusion on keeping code separate MVC

I am learning AngularJS at the moment and I am a little confused about the MVC separation of code throughout the DOM/file structure when using AngularJS.
I learn best when I work on a project. Right now I am working on a simple counter that adds a whole number when a button is pushed. I only have one way working and I am thinking of a better way to do this.
Right now I have this working in the code I am working on from AngularJS documentation itself.
I am probably crazy thinking that this cannot be the best way to do this. From my understanding ng-click is a directive that triggers a specific scope of code within the controller.
Why is Increment code inline within the DOM? As a MVC, should the code be organized to not be all over the place, such as in the main controller.js? I have tried to put the increment += function in a counter object, but could not get it to work, see jsFiddle.
<div ng-controller="MyCtrl">
<button ng-click="char">Charged</button>
<span>Total: {{ count }}</span>
</div>
I get that Apps view information based on expressions, filters, and directives. Directives bind to HTML to change behavior of the HTML. Clicks (with Directive selectors) controllers triggers AngularJS to run functions to update data without the entire page being reloaded.
So the Model is the whole setup.
The View is the expressions, filters, and directives.
Controller is the JS file of code that has objects and functions needed for the HTML Directives.
The example of the documentation has inline controller in the directive ng-click within the button tag…
Does anyone have any advice? Thank you.:)
There is a correct way of doing that in angular via a controller:
http://jsfiddle.net/zhxztysy/1/
Your fiddle was like this
<div ng-controller="MyCtrl">
<button ng-click="char">Charged</button>
<span>Total: {{ count }}</span>
</div>
function MyCtrl($scope) {
$scope.count = 0;
$scope.count = Function (char) {
$scope.count += char;
};}
Changed to this
<div ng-controller="MyCtrl">
<button ng-click="charge(5)">Charged</button>
<span>Total: {{ count }}</span>
</div>
function MyCtrl($scope) {
$scope.count = 0;
$scope.charge = function (char) {
$scope.count += char;
};
}
Can also extended like this
<div ng-controller="MyCtrl">
<button ng-click="charge()">Charged</button>
<span>Total: {{ count }}</span>
</div>
function MyCtrl($scope) {
$scope.count = 0;
$scope.chargingCount = 5;
$scope.charge = function () {
$scope.count += $scope.chargingCount;
};
}
I edited your jsfiddle to work. You have made a syntax error (bound $scope.count to a function and tried to add numbers to it later on)

Passing value from Django view to AngularJS inserted template

Is there a way to pass a value from a Django view to an AngularJS inserted template?
In my view.py I have the code:
count_users = Profile.objects.filter(user_id__gte = 0).count()
context_dict = {'users': count_users}
return render_to_response('dashboard.html', context_dict)
In dashboard.html I am able to insert the user count into the html as follows:
{{ users }}
This works fine but dashboard.html uses AngularJS to insert some more html as follows:
<div ui-view class="fade-in-up">
</div>
Mt problem that the html file inserted by AngularJS does not respond to the:
{{ users }}
Is there a way to pass the value of users through to the AngularJS inserted HTML?
using ng-init you can attach your value into the $scope
<div ui-view class="fade-in-up" ng-init="User='{{user}}' " >
</div>
In your javascript do:
mainModule
.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{$');
$interpolateProvider.endSymbol('$}');
});
This way, if you want to bind an angular variable in the html, you use:
{$ variable $}
If you want to add a Django variable, you use:
{{ variable }}
And your code may work if you leave it as it is, and just add this configuration to the angular module.