Dynamic change of content better ways. AngularJS 1.6 - javascript

I have REST service that gives some information for banner. I want to use this information for dynamic change of slider on main page.
So I simply use $http.get to get data, and then interpolation, with some additional ng-if's to check, if there is specific data, to displaying or not some elements.
<div class="main-block" ng-if="locale==='ru'">
<div ng-repeat="slider in restData.result" ng-class="{'active':$first}" class="slide {{ slider.location }}" ng-style="{'background-image':'url({{ slider.url.url }})'}">
<div class="content-block">
<div class="container">
<div class="right-block">
<h2>{{ slider.text1 }}</h2>
</div>
<div class="clearfix"></div>
<div ng-if="slider.text2 || slider.text3 || slider.text4 || slider.text5" class="offer-block" ng-style="{'background':'rgba({{ slider.color }},0.6)'}">
<div class="offer-block__country">{{ slider.text2 }}</div>
<div class="offer-block__name">
{{ slider.text3 }}
</div>
<div class="offer-block__days">
{{ slider.text4 }}
</div>
<div class="offer-block__date">
{{ slider.text5 }}
</div>
</div>
<div class="clearfix"></div>
<a ng-if="slider.link" ui-sref="shell.tourShow({url:'{{ slider.link }}'})" class="orange-btn">
Подробнее
</a>
</div>
</div>
</div>
</div>
But I feel like there must be better way to work with such type of data manipulation, more readable and understandable. Can you please help to find one, or give a little example, how to do it better.

It is relatively good already, the only thing I would change is not to directly map to ng-repeat="slider in restData.result"
but rather create a $scope variable like
$scope.sliders = {};
// in rest request update the local variable with most recent data
// and then use ng-repeat="slider in sliders"

Related

How to solve error Elements in iteration expect to have 'v-bind:key' directives vue/require-v-for-key in Vuejs?

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app-gridview">
<div>
<button class="button" v-on:click="switchView()"><span>{{ buttonSwitchViewText }}</span></button>
<button class="button" v-on:click="switchData()"><span>{{ buttonSwitchDataText }}</span></button>
</div>
<div v-bind:class="[ isGridView ? 'grid-wrapper' : 'list-wrapper' ]">
<div class="grid-row" v-if="isGridView">
<div class="grid-header" v-for="name in gridData.columns">{{ name }}</div>
</div>
<!-- GridView structure -->
<div v-if="isGridView" class="grid-row" v-for="row in gridData.data">
<div class="list-row-item" v-for="name in gridData.columns">
<div>{{ row[name] }}</div>
</div>
</div>
<!-- ListView structure -->
<div v-if="!isGridView" class="list-row" v-for="row in gridData.data">
<img v-bind:src="row.ImagePath" class="list-image" />
<div class="list-property">
<div class="list-row-item" v-for="name in gridData.columns">
<div class="list-property-name">{{ name }}</div>
<div>{{ row[name] }}</div>
</div>
</div>
</div>
</div>
</div>
Getting error as
error Elements in iteration expect to have 'v-bind:key' directives vue/require-v-for-key
How can I solve this issue, With some reference, I come to know we need to pass v-bind-key for the value, But not sure how to pass it.
Whenever we are using v-for in vuejs, we need to pass a unique value which is key which helps in properly rendering the components whenever the loop runs.
You can pass it like <div class="list-row-item" v-for="(name, index) in gridData.columns" :key="index">
The value of the key needs to be unique.
You should use uniq index inside your loop. Look hear https://v2.vuejs.org/v2/guide/list.html
<div v-if="!isGridView" class="list-row" v-for="(row, index) in gridData.data" :key="index">

How can i render ngx-quill editor content from my database to a view component?

I'm working on an angular blog app that uses ngx-quill as a text editor. I had no trouble adding records to my database. the problem occurs when I try to render content, it's not showing the data.
this is my details-post component HTML where I want to show content:
<article class="post" *ngIf="post$ | async as post; else loading">
<div class="post-thumbnail" style="background-image: url("https://images.unsplash.com/photo-1538370965046-79c0d6907d47?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80");" >
<h1 class="post-title">{{ post.titlePost }}</h1>
<div class="post-meta">February 20, 2020</div>
</div>
<div class="blog-post-content">
{{ post.contentPost }}
</div>
</article>
<ng-template #loading>
<div class="container-spinner">
<mat-spinner></mat-spinner>
</div>
</ng-template>
For ngx-quill you have to either use their own directive:
<quill-view [content]="content" format="text" theme="snow"></quill-view>
or innerHTML. More info here
<div class="ql-container ql-snow" style="border-width: 0;">
<div class="ql-editor" [innerHTML]="byPassedHTMLString">
</div>
</div>
I would suggest using their own directive.
Cheers

Unable to filter data from database due to laravel blade curly braces "{{ }}"

I'm trying to filter data gotten from database with the class="data-groups".
Here is the code:
this.shuffle.filter(function(element, shuffle) {
// If there is a current filter applied, ignore elements that don't match it.
if (shuffle.group !== Shuffle.ALL_ITEMS) {
// Get the item's groups.
var groups = JSON.parse(element.getAttribute('data-groups'));
var isElementInCurrentGroup = groups.indexOf(shuffle.group) !== -1;
// Only search elements in the current group
if (!isElementInCurrentGroup) {
return false;
}
}
var titleElement = element.querySelector('.book-item_title');
var titleText = titleElement.textContent.toLowerCase().trim();
return titleText.indexOf(searchText) !== -1;
});
};
<!-- begin snippet: js hide: false console: true babel: false -->
<div class="grid-shuffle">
<ul id="grid" class="row">
#foreach($libraries as $library)
<li class="book-item small-12 medium-6 columns" data-groups='["{{$library->genre}}"]' data-date-created='{{$library->published}}' data-title='{{ $library->title }}' data-color='{{$library->color}}'>
<div class="bk-img">
<div class="bk-wrapper">
<div class="bk-book bk-bookdefault">
<div class="bk-front">
<div class="bk-cover" style="background-image: url('img/001-small.png')"></div>
</div>
<div class="bk-back"></div>
<div class="bk-left"></div>
</div>
</div>
</div>
<div class="item-details">
<h3 class="book-item_title">{{$library->title}}</h3>
<p class="author">{{$library->author}} • {{$library->published}}</p>
<p>{{$library->synopsis}}</p>
Details
</div>
<div class="overlay-details">
Close
<div class="overlay-image">
<img src="img/001.jpg" alt="Book Cover">
<div class="back-color"></div>
</div>
<div class="overlay-desc activated">
<h2 class="overlay_title">{{$library->title}}</h2>
<p class="author">by {{$library->author}}</p>
<p class="published">{{$library->published}}</p>
<p class="synopsis">{{ $library->synopsis }}</p>
Preview
</div>
<div class="overlay-preview">
Back
<h4 class="preview-title">Preview</h4>
<div class="preview-content">
<h5>Chapter 1</h5>
<p>{{$library->details}}</p>
</div>
</div>
</div>
</li>
#endforeach
</ul>
</div>
The problem is it doesn't work unless I hard code the genre like this
data-groups='["fiction"]'
Now since I'm retrieving data from a database using the foreach loop it means any book out the database is automatically given the "fiction" attribute regardless of its db assigned genre.
Any help on how to solve this will be appreciated.
Found the problem
I was Filtering with this lines of code
All Categories
Fantasy
Sci-Fi
Classics
Fairy Tale
The problem was that the data-group items are case sensitive. So for example I was filtering with "classic" while my database was providing "Classic" therefore making the filter function seem faulty.

What is the proper way of using ng-repeat to set attributes on an element?

So I have the following div:
<div ng-repeat="player in playersScores" class="sb_lane">
<div class='sb_animation drop'></div>
<div lane="{{player.lane}}" class='dropbox' dropbucket>
<div class='sb_lHeader'>
<div class="drop">Lane {{player.lane}}</div>
<div class="drop">{{player.player}}</div>
</div>
<div class="sb_rScore drop">Run : {{cRun}} of {{tRun}}
<div>Run Score</div>
<div >{{player.rScore}}</div>
</div>
<div class="sb_tScore drop">Game Score
<div > {{player.gScore}}</div>
</div>
</div>
</div>
I am getting an error from using {{player.lane}} in the this line:
<div lane="{{player.lane}}" class='dropbox' dropbucket>
My question is this: What is the proper way of using ng-repeat to set attributes on an element?
Simply use
<div lane="player.lane" class='dropbox' dropbucket>
Turns out I had a two way binding in the drag and drop directive that was set to lane. Once I removed that binding, everything worked as expected.
Thanks for the insight everyone..
Z

How to calculate a transaction in ng-if and put a `<div>` only if the condition is true?

i want to add a row only if the x in $scope.grp leaves no remainder when divided by 3. I was trying the following code.
<div class="card">
<div ng-repeat="x in grp">
<div class="row">
<div ng-if="x%3==0">
<div class="row">
</div>
<div class="col col-33">
/my rest of code here/
</div>
</div>
</div>
<div>
any suggestions how to do it?
Not sure whether the following is correct or not. But a way to achieve it is as following.
<div data-ng-app="" data-ng-init="grp=['one','two','three','four','five','six','seven']" class="container">
<div ng-repeat="x in grp" ng-if="$index % 3 == 0" class="row">
<div class="col-xs-3">{{grp[$index]}}</div>
<div class="col-xs-3" ng-if="$index + 1 < grp.length">{{grp[$index+1]}}</div>
<div class="col-xs-3" ng-if="$index + 2 < grp.length">{{grp[$index+2]}}</div>
</div>
<div>
I am assuming grp is a string array and used $index to group.
Jsfiddle
Check this:
if reminder is 0, row will be added
<div class="card">
<div ng-repeat="x in grp">
<div class="row">
<div ng-if="x%3==0">
<div class="row">
reminder 0
</div>
</div>
<div class="col col-33">
my rest of code here
</div>
</div>
</div>
Here is the code for controller
function ctrl($scope){
$scope.grp=[1,2,3];
}
Codepen : http://codepen.io/anon/pen/eJJKwr
I'm not very familiar with angularjs - however your html struct is wrong in this case. Your struct will create an empty "row" column before every third div. I don't know if there is a way to just open a "div" tag in an ng-if and close it at a later point.
You should consider just creating array chunks for your cards. So each chunk will hold 3 cards and then you can loop over the first level of chunks, and then over the second level of your array. It will look something like that:
<div class="card">
<div ng-repeat="grp in chunks">
<div class="row">
<div ng-repeat"x in grp"> // as mentioned, I got no clue about angularjs, so I don't know how to correctly address the values within the groups
<div class="col col-33">
my rest of code here
</div>
</div>
</div>
</div>
</div>
As mentioned before I have no clue about angularjs itself, however you should be able to create chunks (split your array into smaller arrays) like:
var chunks=[[1,2,3],[4,5,6],[7,8,9]];

Categories