Error trying to diff '[object Object]'. Only arrays and iterables are allowed - Angular API Get Request from .Net - asp.net

I'm a on learning stage, and a little bit of a noob, sorry if this is a stupid question. I'm working on a Movie DB project, with movies from live API, Favorite list, JWT auth, etc. I'm now on the end part, have everything done so far, and have one problem. Every person who click's on see details about movie, the movie will be sent on my DB. And with this user can save movie to his favorite table (.net Crud operations). Everything work but when I want to get movies from a table that's between movies table and users table (favorite table many to many relation) I get a error in my swagger everything is working, and I can get every movie that's in favorite, but in angular I user *ngFor, and the error say that it must return a array, but I'm getting a Object, every other get request works only this one doesn't. Here is my code and error:
You can see I get everything I want in console, but UI is Error
Component .ts and HTML:
//HTML
<div *ngFor="let fav of requests" class="col-xl-3 col-lg-4 col-md-6 col-sm-6 col-xs-12">
<div class="card">
<img src="{{fav.Poster}}" class="card-img-top">
<div class="card-body">
<p class="card-text"> {{fav.Title}}</p>
</div>
</div>
</div>
.Ts
export class FavoriteListComponent implements OnInit {
constructor(public service: MovieService) { }
requests: any = [];
ngOnInit(): void {
this.getFav();
}
getFav(){
this.service.getFavorite1().subscribe(
res => {
this.requests = res;
console.log(res)
});
}
}
MovieService
getFavorite1(){
return this.http.get('http://localhost:5002/api/Favorite/getUsersFavorite').pipe(map(res => res));
}
And this is my get request in .Net 5
[Authorize]
[HttpGet("getUsersFavorite")]
public async Task<IActionResult> GetUsersFavoriteMovies()
{
string userId = User.Claims.First(a => a.Type == "UserID").Value;
var user = await _context.DbUsers.Where(n => n.Id == Int32.Parse(userId)).Select(movies => new FavoriteView()
{
ImdbId = movies.Favorites.Select(n => n.ImdbId).ToList(),
Title = movies.Favorites.Select(n => n.Movies.Title).ToList(),
Poster = movies.Favorites.Select(n => n.Movies.Poster).ToList()
}).FirstOrDefaultAsync();
return Ok(user);
}
I tried a lot of thing, the closest I get is this, and when I change in .net request the .FirstOrDefaultAsync() to .ToListAsync(). When I it to ToListAsync I get this:
In this case I don't get any error but nothing is showing in UI
I know the question is big, but I'm desperate, I'm stuck on this a few day's, and every help is great. Thank you!!!

Use this way, it will work.
<ng-container *ngIf="requests">
<div
*ngFor="let fav of requests.imdbId; index as i"
class="col-xl-3 col-lg-4 col-md-6 col-sm-6 col-xs-12"
>
<div class="card">
<img [src]="requests.poster[i]" class="card-img-top" />
<div class="card-body">
<p class="card-text">{{ requests.title[i] }}</p>
</div>
</div>
</div>
</ng-container>
Example:
https://stackblitz.com/edit/angular-ivy-f251ko?file=src%2Fapp%2Fapp.component.html

Related

How to display the messages of sending and receiving based on time

If a sender send a message it comes to right side of the ui and receiver gets from left side of the ui, but when a sender sends an another message to the receiver it should come display at the bottom end , but it shows at the top end
I want to be display the messages as
received message
send message
received message
send message
But here I'm getting the messages like
received message
received message
received message
received message
send message
send message
send message
send message
Here is the code:
const time = new Date();
const formattedTime = time.toLocaleString("en-US", { hour: "numeric", minute: "numeric", seconds: "numeric });
<div className="nano-content pad-all" tabIndex={0} style={{right: '-17px'}}>
<ul className="list-unstyled media-block">
<li className="mar-btm" id="media-left">
{
receiveMessages.map((receivemessage,key) => {
return <div>
<div className="media-left">
<img src="https://bootdey.com/img/Content/avatar/avatar1.png" className="img-circle img-sm" alt="Profile Picture" />
</div>
<div className="media-body pad-hor">
<div className="speech">
<p value={key} className="mar-btm">{receivemessage}</p>
<span class="time_date">{formattedTime}</span>
</div>
</div>
</div>
})
}
</li>
<li className="mar-btm" id="media-right">
{
messages.map((message,key) => {
return <div>
<div className="media-right">
<img src="https://bootdey.com/img/Content/avatar/avatar2.png" className="img-circle img-sm" alt="Profile Picture" />
</div>
<div className="media-body pad-hor speech-right mt-2">
<div className="speech">
<p value={key} className="mar-btm">{message}</p>
<span class="time_date">{formattedTime}</span>
</div>
</div>
</div>
})
}
</li>
</ul>
</div>
Please help me thanks in advance.
You are just mapping one array after the other, so the messages are expected to show like they are.
Instead of just an array of message strings you'd need a more complex object with some metadata: (1) the date the message was sent. (2) who sent it, and of course (3) the message itself. Like:
messsageObj = {
// always good to add an unique id to use as the `key` property when using .map
id: 1,
message: 'My message',
createDate: '25/12/2020 22:00:00',
createUser: 1
}
For example:
// in `mergeMessagesArray` you add all messages to a single list,
// ordering by the date they were sent
const mergedMessages = mergeMessagesArray(sentMessages, receivedMessages)
return (
<div>
{mergedMessages.map(m => (
// use unique id as key to avoid weird bugs
<div key={m.id}
// when mapping the messages array just check the user who created the
// message against your current logged in user and render accordingly
className={m.createUser === currentUser ? 'show-on-right' : 'show-on-left'}>
{m.message}
</div>
)}
</div>
)

First click modal doesn't open in .NET 5 Blazor server side

After loading a page, the very first click on any card doesn't open the modal window, but the next click and after, it will lunch the modal as it expected. I am not sure what caused this issue.
<div class="card-columns">
#foreach (var project in ProjectService.GetProjects())
{
<div class="card">
<div class="card-img" #onclick="(e => SelectProject(project.Id))" data-toggle="modal" data-target="#projectModal" style="background-image: url('#project.Image'); cursor: pointer;"></div>
<div class="card-body">
<h5 class="card-title">#project.Title</h5>
</div>
</div>
}
</div>
#if (selectedProject != null)
{
<div class="modal fade" id="projectModal" tabindex="-1" role="dialog" aria-labelledby="projectTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
...
C#:
#code {
Project selectedProject;
string selectedProjectId;
void SelectProject(string projectId)
{
selectedProjectId = projectId;
selectedProject = ProjectService.GetProjects().First(x => x.Id == projectId);
Console.WriteLine("hi");
}
The very first click, it reads the Console.WriteLine but doesn't show the modal, so I know selectedProject is not null and it suppose to show the modal. I tried to comment out all the javascript code I had and still have the issue. I also downloaded a new copy of bootstrap and replaced it into my project since I replaced some of the values (mostly fonts) by mistake and I found out that I should never edit the bootsrap. Still have the issue. There is also no console error in the browser.
So, this is not quite right, and I would say it's a lazy way to fix this issue because I still don't know what the root of the issue was, but I solved my problem by introducing a mouseover event to the card-img div:
<div class="card-img" #onclick="(e => SelectProject(project.Id))" #onmouseover="(e => start(project.Id))" data-toggle="modal">
C#
bool unlock;
void start(string projectId)
{
if (!unlock)
{
selectedProjectId = projectId;
selectedProject = ProjectService.GetProjects().First(x => x.Id == projectId);
unlock = true;
}
}
Now for the first time and only once when the mouse is going over a card, it will run the open modal but since it doesn't open for the first attempt, it basically does nothing but also make it interactable with the first click attempt.

Having Issues with 2sxc Data Import

Needing some help with Showing Imported data on my production site after exporting it from staging. After finishing up my updates on staging I installed 2sxc module on my production created my content types and my 2 views (Current award winners and past award winners). After that I imported my content type data which completed successfully and I can see all my imported data from admin. However, I have not been able to get my data to show for this my Current award winners view as it is on my staging. My view template is as follow:
<div class="row">
#{var Count = 1;}
#foreach (var e in List)
{
var Content = e.Content;
<div class="col-sm-4 item-#Content.EntityId">
<div class="img-thumb item sc-element">
#Content.Toolbar
<a href="#Content.URL" title="#Content.Title">
<img src="#Content.Image?w=200&h=200&mode=crop" class="img-responsive" title="#Content.EntityTitle">
</a>
</div>
<p class="img-caption">
#Content.Title
</p>
</div>
if ( Count %3 == 0 ) {
<div class="clearfix hidden-xs"></div>
}
if ( Count %2 == 0 ) {
<div class="clearfix hidden-sm hidden-md hidden-lg"></div>
}
Count++;
}
</div>
I have set everything up identical to how I have my stage set up. I did find a slack Imported data not display, and updated my code from #foreach (var e in List) to #foreach (var Content in AsDynamic(App.Data["DCC Awards"])), which eventually did start showing my data. However, it showed all data for both of my views (current and past). This template should only show my current winners.
So what your export/import seems to miss is the "which items were assigned to what dnn-module + their respective order". For this, you must export an app with the "Keep Content-Groups" check box activated. Best review the instructions on https://2sxc.org/en/Learn/Copy-Duplicate-an-entire-Site

Meteor Method: I keep getting a insert failed:Access Denied error on the Console

I cant figure out why I am getting this error. I have created a Meteor Method. Maybe I just need a second set of eyes and point out my mistake. Im creating a Instant Messaging App, where online users can have one on one chats. As soon as I click on the online user(routing). The console instantly has an
insert failed:access denied.
If I attempt to send a message, This is the error I get.
j…y.Event {originalEvent: Event, type: "submit", timeStamp:
1455207989065, jQuery1112075371492956765: true, which: undefined…}
meteor.js:862 insert failed: Access denied meteor.js:862 update
failed: Access denied 17799meteor.js:862 insert failed: Access denied
Im really new to Meteor and any help or advice would be very much appreciated.
Here is my HTML
<template name="chat_page">
<h2>Type in the box below to send a message!</h2>
<div class="row">
<div class="col-md-12">
<div class="well well-lg">
{{#each messages}}
{{> chat_message}}
{{/each}}
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<form class="js-send-chat">
<input class="input" type="text" name="chat" placeholder="type a message here...">
<button class="btn btn-default">send</button>
</form>
</div>
</div>
</template>
<!-- simple template that displays a message -->
<template name="chat_message">
<div class = "container">
<div class = "row">
<img src="/{{profile.avatar}}" class="avatar_img">
{{username}} said: {{text}}
</div>
</div>
<br>
</template>
Client Side
Template.chat_page.helpers({
messages:function(){
var chat = Chats.findOne({_id:Session.get("chatId")});
return chat.messages;
},
other_user:function(){
return ""
},
});
Template.chat_page.events({
'submit .js-send-chat':function(event){
console.log(event);
event.preventDefault();
var chat = Chats.findOne({_id:Session.get("chatId")});
if (chat){
var msgs = chat.messages;
if (!msgs){
msgs = [];
}
msgs.push({text: event.target.chat.value});
event.target.chat.value = "";
chat.messages = msgs;
Chats.update(chat._id, chat);
Meteor.call("sendMessage", chat);
}
}
})
Method
Meteor.methods({
sendMessage: function (chat) {
Chats.insert({
chat: chat,
createdAt: new Date(),
username: Meteor.user().profile.username,
avatar: Meteor.user().profile.avatar,
});
},
});
Do you still have insecure and autopublish package ?
Chats.update(chat._id, chat);
This part seems a little weird to me.
a basic update to a collection is : Chats.update({_id : chat._id}, {$set : {message : whateverMymsgis }}); Meteor is kind of strict with the update method you will always need to pass the _id to update something.
If you don't have autopublish and insecure packages, have you made all the allow / publish / subcription part to your collections ??
Hope it will help :)
This has happened because you removed insecure package and have not specified any allow/deny for your chat collection and also your meteor method has been written on the client side.
The quick and proper solution would be moving your meteor method to the server side.

Template helper crashing app

My app is crashing my browser after implementing this columnWidth helper method. All I'm trying to do is rotate between col-md-7 and col-md-5 (Bootstrap classes) so that no two consecutive posts are the same width.
columnWidth: function() {
if (Session.get('columnWidth') === 'col-md-7') {
Session.set('columnWidth', 'col-md-5');
} else {
Session.set('columnWidth', 'col-md-7');
}
return Session.get('columnWidth');
}
The post template:
{{#each this}}
<div class="{{columnWidth}}">
<img src="{{image}}" height="350" width="{{imageWidth}}" alt="">
<div class="content">
<h2>{{title}}</h2>
<p>{{content}}</p>
<span class="dateAuthored">{{date}}</span>
</div>
</div>
{{/each}}
this refers to:
data: function() {
return Articles.find();
}
Any ideas why this is happening? I'm not receiving any errors. The browser tab just becomes unresponsive. Thanks.
You are constantly setting the same reactive variable so for example with the first div when the helper is called it will set it to col-md-7, then when it is called for the 2nd row you are changing the same variable to col-md-5 which is problematic for 2 reasons:
a) the template will redraw the first column and so they will both be col-md-5
b) the same helpers will get called again. I believe your browser crashes because you have created an infinite loop. Try console logging something inside your columnWidth helper and see how many times it gets called.
To achieve what you want you need to get the index of the {{#each }} loop and then have the column class dependent on whether it's odd or even. Unfortunately getting the index in meteor handlebars is a little tricky.
Try:
{{#each articles}}
<div class="{{columnWidth index}}">
<img src="{{image}}" height="350" width="{{imageWidth}}" alt="">
<div class="content">
<h2>{{title}}</h2>
<p>{{content}}</p>
<span class="dateAuthored">{{date}}</span>
</div>
</div>
{{/each}}
Then the following helpers:
articles: function() {
//'this' in this context should work.
//if not just replace with Articles.find().map(...
var articles = this.map(function(article, index) {
var i = _.extend(article, {index: index});
return i;
});
return articles;
},
columnWidth: function(index) {
if (index % 2 === 0)
return "col-md-5";
else
return "col-md-7"
}

Resources