_isRowLoaded and _loadMoreRows not getting called react virtualized - react-virtualized

My _loadMoreRows and _isRowLoaded are not getting called, so loadedRowsMap remains empty and I am unable to identify the rows loaded to avoid making HTTP request .
Here's my complete code :
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {formatDate} from '../../helper/date';
import { recentActivitiAction } from '../actions/dashboardAction';
import { BeatLoader } from 'react-spinners';
import {AutoSizer, List, CellMeasurer, InfiniteLoader, CellMeasurerCache} from 'react-virtualized';
import styles from '../../css/AutoSizer.module.css';
import Skeleton from 'react-skeleton-loader';
const STATUS_LOADING = 1;
const STATUS_LOADED = 2;
const mapStateToProps = (state) => {
return {
recentActList: state.dashboardReducer.recentActList,
activitiLoading: state.dashboardReducer.activitiLoading
}
}
const mapDispatchToProps = (dispatch) => {
return {
getRecentActivites: (postData, callback) => {
dispatch(recentActivitiAction(postData, callback));
}
};
}
class RecentActivitiComp extends Component {
constructor(props) {
super(props);
this.state = {
loadedRowCount: 0,
loadedRowsMap: {},
loadingRowCount: 0,
};
this.cache = new CellMeasurerCache({
fixedWidth: true,
defaultHeight: 100
});
this._timeoutIdMap = {};
this._isRowLoaded = this._isRowLoaded.bind(this);
this._loadMoreRows = this._loadMoreRows.bind(this);
this.renderRow = this.renderRow.bind(this);
this.onRowsRendered = this.onRowsRendered.bind(this);
this.noRowsRenderer = this.noRowsRenderer.bind(this);
}
componentWillUnmount() {
Object.keys(this._timeoutIdMap).forEach(timeoutId => {
clearTimeout(timeoutId);
});
}
componentDidMount() {
var postData = {
"userName": "admin",
"queryType": "GET_RECENT_PROJECTS",
"data": {
pageStart: 1,
pageEnd: 20
}
};
this.props.getRecentActivites(postData, this.recentActResponse.bind(this));
}
updateDimensions() {
this.cache.clearAll();
this.activitiList.recomputeRowHeights();
}
recentActResponse(response) {
if (response.status === "FAILED") {
// handle error
}
}
_fieldGenerator(row, index) {
var formattedDate = formatDate(row.lastModified),
output = '', JSX = '';
if(formattedDate) {
formattedDate = formattedDate.split('-');
output = (
<div className="project-info-value byline">
<span>{formattedDate[0]}<sup>{formattedDate[1]}</sup> {formattedDate[2]} {formattedDate[3]}</span> by <a>{row.modifiedBy}</a>
</div>
)
} else {
output = (
<div className="project-info-value byline">
<span>Invalid Date by </span> <a>{row.modifiedBy}</a>
</div>
)
}
if(row.action === "upcoming-release") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.action}</h2>
{output}
<p className="excerpt">{row.notes}<a> Read More</a></p>
</div>
</div>
</li>
} else if(row.action === "created") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.type} <a>{row.name}</a> {row.action}</h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
} else if(row.action === "modified") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.type} <a>{row.name}</a> {row.action}</h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
} else {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title"><a>{row.person}</a> added to <a>{row.addedTo}</a></h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
}
return JSX;
}
renderRow({ index, key, style, parent }) {
var JSX = '', content = '';
const list = this.props.recentActList
const {loadedRowsMap} = this.state;
if (loadedRowsMap[index] === STATUS_LOADED) {
const row = list[index];
JSX = this._fieldGenerator(row, index);
content = (
JSX
);
} else {
content = (
<div className={styles.placeholder} style={{width: 480}} />
);
}
return (
<CellMeasurer
cache={this.cache}
columnIndex={0}
key={key}
parent={parent}
rowIndex={index}
>
{({ measure }) => (
<div key={key} style={{...style}} onLoad={measure}>
{content}
</div>
)}
</CellMeasurer>
);
}
_isRowLoaded({index}) {
const {loadedRowsMap} = this.state;
return !!loadedRowsMap[index]; // STATUS_LOADING or STATUS_LOADED
}
_loadMoreRows({startIndex, stopIndex}) {
const {loadedRowsMap, loadingRowCount} = this.state;
const increment = stopIndex - startIndex + 1;
for (var i = startIndex; i <= stopIndex; i++) {
loadedRowsMap[i] = STATUS_LOADING;
}
this.setState({
loadingRowCount: loadingRowCount + increment,
});
const timeoutId = setTimeout(() => {
const {loadedRowCount, loadingRowCount} = this.state;
delete this._timeoutIdMap[timeoutId];
for (var i = startIndex; i <= stopIndex; i++) {
loadedRowsMap[i] = STATUS_LOADED;
}
this.setState({
loadingRowCount: loadingRowCount - increment,
loadedRowCount: loadedRowCount + increment,
});
promiseResolver();
}, 1000 + Math.round(Math.random() * 2000));
this._timeoutIdMap[timeoutId] = true;
let promiseResolver;
return new Promise(resolve => {
promiseResolver = resolve;
});
}
noRowsRenderer() {
return <div className={styles.noRows}>No rows</div>;
}
onRowsRendered({overscanStartIndex, overscanStopIndex, startIndex, stopIndex}) {
const list = this.props.recentActList.length ? this.props.recentActList : [];
const {loadedRowsMap} = this.state;
console.log(startIndex, stopIndex, this.state.loadedRowCount);
// if(startIndex + 10 === list.length && this._isRowLoaded(startIndex) !== STATUS_LOADED) {
// var postData = {
// "userName": "admin",
// "queryType": "GET_RECENT_PROJECTS",
// "data": {
// pageStart: 1,
// pageEnd: 10
// }
// };
// this.props.getRecentActivites(postData, this.recentActResponse.bind(this));
// }
}
render() {
const list = this.props.recentActList.length ? this.props.recentActList : [];
const {loadedRowCount, loadingRowCount} = this.state;
return (
<div className="recent left_panel">
<div className="x_panel">
<div className="x_title sub_title">
<h2>Recent Activites</h2>
</div>
<div className="x_content">
<div className="dashboard-widget-content">
<ul className="list-unstyled timeline widget">
<InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={list.length}>
{({onRowsRendered, registerChild}) => (
<div className={styles.list}>
<AutoSizer onResize={this.updateDimensions.bind(this)}>
{({width, height}) => (
<List
ref={(ref) => {
this.activitiList = ref;
registerChild(ref);
}}
noRowsRenderer={this.noRowsRenderer}
onRowsRendered={this.onRowsRendered}
deferredMeasurementCache={this.cache}
width={width}
height={height}
deferredMeasurementCache={this.cache}
rowHeight={this.cache.rowHeight}
rowRenderer={this.renderRow}
rowCount={list.length} /* Initially render 20 records */
/>
)}
</AutoSizer>
</div>
)}
</InfiniteLoader>
</ul>
{/* <div className="align-right">
<a href="http://karthik.jivox.com/studio/eam/production/index.php#"
className="btn-jivox-1">
<span className="btn-icon">
<i className="fas fa-chevron-down" aria-hidden="true"></i>
</span> Show More Activities
</a>
</div> */}
</div>
</div>
</div>
</div>
);
}
}
const RecentActiviti = connect(mapStateToProps, mapDispatchToProps)(RecentActivitiComp);
export default RecentActiviti;
As you can see I am making API call at didMount phase and therefore populating my redux store with the data. Data is coming fine. But isRowLoaded and loadMoreRows are not getting called.
I have debugged the sample code of infiniteLoader.example.js, there during the inital render those two functions are called and properly set loadedRowsMap.
What I am doing wrong here ? :-( Any help would be greatly appreciated .

I have resolved the issue after making some changes.
const mapStateToProps = (state) => {
return {
myList: state.dashboardReducer.myList
}
}
const list = this.props.myList.length ? this.props.recentActList : [];
const rowCount = list.length + (moreToBeLoaded ? 1 : 0);
To know why 1 more row loaded pls check this post react-virtualized InfiniteLoader/List - working example using AJAX
So the issue in my code was I was writing my custom onRowsRendered function and it was not handling the response correctly. Now I changed the code to use the one passed by InfiniteLoader.
Hope that helps.
<InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={rowCount}>
{({onRowsRendered, registerChild}) => (
<div className={styles.list}>
<AutoSizer onResize={this.updateDimensions.bind(this)}>
{({width, height}) => (
<ActiviitiList
ref={(ref) => {
this.activitiList = ref;
registerChild(ref);
}}
width={width}
height={height}
onRowsRendered={onRowsRendered}
rowCount={rowCount}
rowHeight={this.cache.rowHeight}
rowRenderer={this._rowRenderer}
overscanRowCount={3}
deferredMeasurementCache={this.cache}
/>
)}
</AutoSizer>
</div>
)}
</InfiniteLoader>

(The code you've posted has a lot going on; you'll probably get better responses if you remove the parts that aren't related to your question.)
My advice is to take a look at the values you're getting for list.length, which you're passing to InfiniteLoader's rowCount prop. InfiniteLoader will only call loadMoreRows if rowCount is higher than the number of rows it has data for.
For example: during the first render, the value is 0, because you have not fetched any data yet. This prevents a call to loadMoreRows during the first render.
I also noticed that you are keeping loadedRowCount and loadingRowCount in state, but you never use them for anything. I don't think that's related to your issue, but it's also probably not intentional.

Related

Google style pagination

I'm trying to implement google stlye pagination that will allow me to select page 1, 2, 3 and so on. Currently I have functionality that will bring me to the next page and previous page. As you can see the api will return 5 hotels per page. I'm new to angular and node so I'm not quite sure how to do this. Any help would be great.
You can see below my .ts file and .html file.
import { Component } from '#angular/core';
import { WebService } from './web.service';
import { AuthService } from './auth.service';
#Component({
selector: 'hotels',
templateUrl: './hotels.component.html',
styleUrls: ['./hotels.component.css']
})
export class HotelsComponent {
constructor(private webService: WebService, private authService: AuthService) {}
ngOnInit() {
if (sessionStorage.start) {
this.start = sessionStorage.start;
}
this.webService.getHotels(this.start);
}
nextPage() {
this.start = Number(this.start) + 5;
sessionStorage.start = Number(this.start);
this.webService.getHotels(this.start);
}
previousPage() {
if (this.start > 0) {
this.start = Number(this.start) - 5;
sessionStorage.start = Number(this.start);
this.webService.getHotels(this.start);
}
}
hotel_list;
start = 0;
}
<div class="container" style="margin-top:100px;">
<div class="row">
<div class="col-sm-12">
<div *ngFor="let hotel of webService.hotel_list | async">
<div class="card text-white bg-primary mb-3"
[routerLink]="['/hotels', hotel._id]" style="cursor: pointer">
<div class="card-header">
{{ hotel.Name }}
</div>
<div class="card-body">
This hotel is based in
{{ hotel.Location }}
</div>
<div class="card-footer">
{{ hotel.review_count }}
reviews available
</div>
</div>
</div>
</div> <!-- col -->
</div> <!-- row -->
<div class="row">
<div class="col-sm-6">
<button (click)="previousPage()">Previous</button>
</div>
<div class="col-sm-6 text-right">
<button (click)="nextPage()">Next</button>
</div>
</div>
</div> <!-- container -->
Web Service
import { Http, URLSearchParams } from '#angular/http';
import { Injectable } from '#angular/core';
import 'rxjs/add/operator/toPromise';
import { Subject } from 'rxjs/Rx';
#Injectable()
export class WebService {
hotelID;
private hotels_private_list = [];
private hotelsSubject = new Subject();
hotel_list = this.hotelsSubject.asObservable();
private hotel_private_list = [];
private hotelSubject = new Subject();
hotel = this.hotelSubject.asObservable();
private reviews_private_list = [];
private reviewsSubject = new Subject();
reviews = this.reviewsSubject.asObservable();
url: string = 'http://localhost:3000/api/hotels/';
hotelsArray = [];
constructor(private http: Http) {
}
getHotels(start) {
return this.http.get(
'http://localhost:3000/api/hotels?start=' + start)
.subscribe(response => {
this.hotels_private_list = response.json();
this.hotelsSubject.next(this.hotels_private_list);
})
}
getHotel(id: string) {
return this.http.get(
'http://localhost:3000/api/hotels/' + id)
.subscribe(response => {
this.hotel_private_list = [];
this.hotel_private_list.push(response.json());
this.hotelSubject.next(this.hotel_private_list);
this.hotelID = id;
})
}
getReviews(id) {
this.http.get(
'http://localhost:3000/api/hotels/' + id + '/reviews')
.subscribe(
response => {
this.reviews_private_list = response.json();
this.reviewsSubject.next(
this.reviews_private_list);
}
)
}
postReview(review) {
let urlSearchParams = new URLSearchParams();
urlSearchParams.append('username', review.name);
urlSearchParams.append('text', review.review);
urlSearchParams.append('stars', review.stars);
this.http.post(
"http://localhost:3000/api/hotels/" +
review.hotelID + "/reviews",
urlSearchParams)
.subscribe(
response => {
this.getReviews(review.hotelID);
}
)
}
}
Create a reusable pagination component as follow.
import {
Component,
Input,
Output,
EventEmitter
} from '#angular/core';
import { OnChanges } from '#angular/core';
#Component({
selector: 'pagination',
templateUrl: './pagination.component.html',
styleUrls: ['./pagination.component.css']
})
export class PaginationComponent implements OnChanges {
#Input('total-items') totalItems;
#Input('page-size') pageSize;
#Output('page-changed') pageChanged = new EventEmitter();
pages: any[];
currentPage = 1;
page: number;
ngOnChanges() {
this.currentPage = 1;
var pagesCount = Math.ceil(this.totalItems / this.pageSize);
this.pages = [];
for (var i = 1; i <= pagesCount; i++)
this.pages.push(i);
}
changePage(page) {
this.currentPage = page;
this.pageChanged.emit(page);
}
previous() {
if (this.currentPage == 1)
return;
this.currentPage--;
this.pageChanged.emit(this.currentPage);
}
next() {
if (this.currentPage == this.pages.length)
return;
this.currentPage++;
this.pageChanged.emit(this.currentPage);
}
}
And below is the view for the component
<nav *ngIf="totalItems > pageSize">
<ul class="pagination pagination-sm">
<li [class.disabled]="currentPage == 1">
<a class="pagetag" (click)="previous()" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<li [class.active]="currentPage == page" *ngFor="let page of pages" (click)="changePage(page)">
<a class="pagetag" *ngIf="page < currentPage+5 && page > currentPage-5">{{ page }}</a>
</li>
<li [class.disabled]="currentPage == pages.length">
<a class="pagetag" (click)="next()" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
And you can use it from your page like this.
In the component you want to use the pagination, pass the page number to your service. Note that your API should be able to accept a page number and accordingly return the data:
private getDataFromServise(pageNumber) {
this.webService.getHotels(pageNumber)
.subscribe(result => { this.result = result});
}
onPageChange(page) {
this.getDataFromServise(page);
}
<div class="text-center">
<pagination [total-items]="total-item-count" [page-size]="PAGE_SIZE" (page-
changed)="onPageChange($event)"></pagination>
</div>
You can find the code for pagination component on my github page.
pagination
I have been using this pagination-component in few projects and it serves the purpose. I hope it helps.

How to integrate and send image crop in this code (angular2-img-cropper)?

I need to know how to send the crooked image to my backend because it is sending the original image without the crop and I can not manage to integrate it.
I use this library: https://github.com/cstefanache/angular2-img-cropper
I think I have to see how to take the data variable but I have no idea how
This is my HTML code:
<div class="card-body">
<h4 class="card-title">Fotografia del usuario</h4>
<h6 class="card-subtitle">{{usuario.nombre}}</h6>
<img-cropper [image]="data" [settings]="cropperSettings" (change)="seleccionImagen($event.target.files[0])"></img-cropper><br>
<img [src]="data.image" [width]="cropperSettings.croppedWidth" [height]="cropperSettings.croppedHeight">
<!-- <img class="img-fluid" [src]="usuario.img | imagen" alt="">
<input class="btn-top" (change)="seleccionImagen($event.target.files[0])" type="file" name="" id=""> -->
<button type="button" (click)="cambiarImagen()" [disabled]="!imagenSubir" mat-raised-button color="primary" class="btn btn-success btn-top">Actualizar Foto</button>
</div>
[![Screen 2][2]][2]
this is my component.ts
import { Component, OnInit, ViewChild } from '#angular/core';
import { UsuarioService } from '../../services/usuario/usuario.service';
import { Usuario } from '../../models/usuario.model';
import {ImageCropperComponent, CropperSettings} from 'ng2-img-cropper';
#Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css'],
declarations: [ImageCropperComponent]
})
export class ProfileComponent implements OnInit {
usuario: Usuario;
imagenSubir: File;
data: any;
cropperSettings: CropperSettings
constructor(
public _usuarioService: UsuarioService) {
this.cropperSettings = new CropperSettings();
this.cropperSettings.width = 100;
this.cropperSettings.height = 100;
this.cropperSettings.croppedWidth = 100;
this.cropperSettings.croppedHeight = 100;
this.cropperSettings.canvasWidth = 400;
this.cropperSettings.canvasHeight = 300;
this.data = {};
}
ngOnInit() {
this.usuario = this._usuarioService.usuario;
}
guardar(usuario: Usuario) {
this.usuario.nombre = usuario.nombre;
if ( !this.usuario.google) {
this.usuario.email = usuario.email;
}
this._usuarioService.actualizarUsuario( this.usuario )
.subscribe(resp => {
console.log(resp);
});
}
seleccionImagen( archivo: File ) {
if ( !archivo ) {
this.imagenSubir = null;
return;
}
this.imagenSubir = archivo;
}
cambiarImagen() {
this._usuarioService.cambiarImagen( this.imagenSubir, this.usuario._id );
}
}

VueJS: changing number of paginate values?

My problem is: I'm trying to do a pagination function to my datatable, it works fine but when I change the limit of items in my table, the total of pages doesn't update. How can I proceed? I have this filter:
filters: {
paginate: function(list) {
this.resultCount = this.movimientos.length;
if (this.currentPage >= this.totalPages) {
this.currentPage = Math.max(0, this.totalPages - 1);
}
var index = this.currentPage * this.upperLimit;
return this.movimientos.slice(index, index + this.upperLimit);
}
}
And here I'm calculating the number of pages
computed: {
totalPages: function() {
return Math.ceil(this.resultCount / this.itemsPerPage);
}
},
methods: {
setPage: function(pageNumber) {
this.currentPage = pageNumber;
},
<div v-for="pageNumber in totalPages" class="c-paginacao__select">
<a href="#" v-on:click.prevent="setPage(pageNumber)">
<span class="active">{{pageNumber+1}}</span>
</a>
</div>

Custom pagination in Swiper

i'm using Swiper and want custom pagination. This question was answered here, but i misunderstood, how to make that pagination clickable, nothing worked. What am i doing wrong?
$(document).ready(function () {
var mySwiper = new Swiper('.swiper-container', {
nextButton: '.swiper-button-next'
, prevButton: '.swiper-button-prev'
, pagination: '.swiper-pagination'
, paginationClickable: true
, paginationHide: false
, paginationType: 'custom'
, paginationElement: 'div'
, paginationCustomRender: function (swiper, current, total) {
var names = [];
$(".swiper-wrapper .swiper-slide").each(function (i) {
names.push($(this).data("name"));
});
var text = "";
for (let i = 1; i <= total; i++) {
if (current == i) {
text += "<div class='swiper-pagination-container swiper-pagination-container-active'><div class='swiper-pagination-icon swiper-pagination-icon-active'></div><div>" + names[i] + "</div></div>";
}
else {
text += "<div class='swiper-pagination-container'><div class='swiper-pagination-icon'></div><div>" + names[i] + "</div></div>";
}
}
return text;
}
});
$(".swiper-pagination-container").on("click", function () {
mySwiper.slideTo($(".swiper-pagination-container").index(this) + 1);
});
}
The difference is that i placed .swiper-pagination div outside the .swiper-wrapper:
<div class="swiper-pagination"></div>
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" data-name="7 сентября">Slide 1</div>
<div class="swiper-slide" data-name="10 декабря">Slide 2</div>
<div class="swiper-slide" data-name="14-23 декабря">Slide 3</div>
<div class="swiper-slide" data-name="30 декабря">Slide 4</div>
<div class="swiper-slide" data-name="5-6 февраля">Slide 5</div>
<div class="swiper-slide" data-name="8 февраля">Slide 6</div>
<div class="swiper-slide" data-name="9 февраля">Slide 7</div>
</div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
It's simple, try it:
window.mainSlider = new Swiper('.swiper-container', {
nextButton: '.swiper-button-next'
, prevButton: '.swiper-button-prev'
, pagination: '.swiper-pagination'
, paginationClickable: true
, paginationHide: false
paginationBulletRender : function (index, className) {
var slide = $('.' + this.wrapperClass).find('[data-name]')[index],
label = $(slide).attr('data-name');
return '<span class="' + className + '">' + (typeof label !== 'undefined' ? name : '') + '</span>';
}
});
I tried this, it works on swiper with loop set to true, if loop set to false, simply remove +1 from the index will do.
pagination: {
el: $('.your_class').find('.swiper-pagination'),// to find the swiper-pagination you put outside of the swiper-container
clickable: true,
renderBullet: function (index, className) {
var slider_array = [];
var el = $('.swiper-container')
el.find('[data-name]').each(function () {
slider_array.push($(this).data('name'));
});
console.log(slider_array);
return '<span class="' + className + '">' + slider_array[index + 1] + '</span>';
}
}

HttpPostedFileBase always remaining null mvc 5

I know this question asked many times, but no answer of them work for me.
My view like...
<div class="form-group">
#Html.LabelFor(model => model.VHF, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.VHF)
#Html.ValidationMessageFor(model => model.VHF)
</div>
</div>
#using (Html.BeginForm("Create", "Radio", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="uploadFile" />
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
My controller...
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Model_No,Manufacturer_Id,Display,Channel_Capacity,Max_Freq_Separation,UHF_R1,UHF_R2,VHF,Pic")] sys_Radio_Models radioModels, HttpPostedFileBase uploadFile)
{
if (ModelState.IsValid)
{
if(uploadFile != null && uploadFile.ContentLength > 0)
{
//File size must be 2 MB as maximum
if (uploadFile.ContentLength > (2 * 1024 * 1024))
{
ModelState.AddModelError("CustomError", "File size must be less than 2 MB");
return View();
}
//File types allowed : jpeg, jpg, png, gif and tif
if (!(uploadFile.ContentType == "image/jpeg"
|| uploadFile.ContentType == "image/jpg"
|| uploadFile.ContentType == "image/png"
|| uploadFile.ContentType == "image/gif"
|| uploadFile.ContentType == "image/tif"))
{
ModelState.AddModelError("CustomError", "File types allowed : jpeg, jpg, png, gif and tif");
return View();
}
byte[] data = new byte[uploadFile.ContentLength];
uploadFile.InputStream.Read(data, 0, uploadFile.ContentLength);
radioModels.Pic = data;
}
else
{
// Set the default image:
var img = Image.FromFile(Server.MapPath(Url.Content("~/assets/img/nopic.png")));
var ms = new MemoryStream();
img.Save(ms, ImageFormat.Png);
ms.Seek(0, SeekOrigin.Begin);
radioModels.Pic = new byte[ms.Length];
ms.Read(radioModels.Pic, 0, (int)ms.Length);
}
db.sys_Radio_Models.Add(radioModels);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.Manufacturer_Id = new SelectList(db.sys_Manufacturers, "Manufacturer_Id", "Manufacturer_Name_a", radioModels.Manufacturer_Id);
return View(radioModels);
}
So, what is my mistake...
Thanks

Resources