block of coding running twice - flutter

So am having a scroll listener to get more data now the problem is that when the listener calls the function for more data then am having 4 if conditions but the function is running the if condition twice i don't understand the logic behind it.
MyCode:-
void _scrollListener()async{
if (!loading) {
if (scrollController.position.pixels == scrollController.position.maxScrollExtent) {
setState(() => load = true);
await clearEmptyDocs();
getMoreData();
}
}
}
getMoreData()async
{
var quicks;
var posts;
if(publicPostsDocuments.isNotEmpty)
{
print('1\n\n\n\n');
posts=await getPublicPosts();
}
if(publicQuicksDocuments.isNotEmpty)
{
print('2\n\n\n\n');
quicks=await getPublicQuicks();
}
if(publicPostsDocuments.isEmpty)
{
print('3\n\n\n\n');
posts=await getPublicDocuments();
}
if(publicQuicksDocuments.isEmpty)
{
print('4\n\n\n\n');
quicks=await getPublicDocumentsForQuicks();
}
setState(() {
load=false;
});
}
Here am having four lists and based on them am having if blocks so when lists are not empty then it should simply print 1 and 2 and then exit but it is printing 1,2,1,2 i.e. first 2 if blocks are running twice.

Related

Flutter: Failed assertion: 'file.absolute.existsSync()': is not true

In my app, a user can send a file to others in a group chat. First, the user records some audio using their mic. The file is then touched up using FFMPEG. Then, the file is uploaded to Firebase Cloud Storage and if this is successful, a record is written in Firebase Realtime Database.
I'm getting the error below when the user records a long audio file and then presses submit. It almost seems as though FFMPEG hasn't finished processing the file...but I thought I used my async/await correctly to make sure that this processing is finished before moving on?
##MyAppFile## saveMyAppFileToCloudStorage Error: 'package:firebase_storage/src/reference.dart': Failed assertion: line 127 pos 12: 'file.absolute.existsSync()': is not true.
Psuedo-code:
User records audio
Audio file is processed using FFMPEG and the new processed file is created on the user's phone
User hits submit, uploading the file to Cloud Storage and, if successful, writing a record to Realtime Database
Order of Functions After User Hits Submit:
msgInput.dart -> sendMyAppFile()
msgInput.dart -> prepareMyAppFileForSending()
msgInput.dart -> runFFMPEGHighLow()
message_dao.dart -> sendMyAppFile()
message_dao.dart -> saveMyAppFileToCloudStorage() //ERROR COMES FROM THIS FUNCTION
The Code:
//msgInput.dart
Future<void> sendMyAppFile() async {
if (sendableMyAppFileExists == 1) {
final MyAppFileReadyToBeSent = await prepareMyAppFileForSending();
if (MyAppFileReadyToBeSent == '1') {
messageDao.sendMyAppFile(MyAppFile, filepath, filename);
} else {
}
}
setState(() {
sendableMyAppFileExists = 0;
});
}
Future<String> prepareMyAppFileForSending() async {
if (sendableMyAppFileExists == 1) {
if (recordedMyAppFileFilterID == '1') {
await runFFMPEGHighLow('1');
return '1';
}
if (recordedMyAppFileFilterID == '2') {
await runFFMPEGHighLow('2');
return '1';
}
}
return '0';
}
Future<void> runFFMPEGHighLow(String filterID) async {
if (filterID != '1' && filterID != '2') {
return;
}
if (sendableMyAppFileExists == 1) {
if (filterID == '1') {
await FFmpegKit.executeAsync(/*...parms...*/);
setState(() {
currentMyAppFileFilename = currentMyAppFileFilename + '1.mp3';
});
}
if (filterID == '2') {
await FFmpegKit.executeAsync(/*...parms...*/);
setState(() {
currentMyAppFileFilename = currentMyAppFileFilename + '2.mp3';
});
}
}
}
//message_dao.dart
void sendMyAppFile(ChatData MyAppFile, String filepath, String filename) {
saveMyAppFileToCloudStorage(filepath, filename).then((value) {
if (value == true) {
saveMyAppFileToRTDB(MyAppFile);
}
});
}
Future<bool> saveMyAppFileToCloudStorage(String filepath, String filename) async {
//filepath: /data/user/0/com.example.MyApp/app_flutter/MyApp/MyAppAudioFiles/MyAppFiles/2d7af6ae-6361-4be5-8209-8498dd17d77d1.mp3
//filename: 2d7af6ae-6361-4be5-8209-8498dd17d77d1.mp3
_firebaseStoragePath = MyAppFileStorageDir + filename;
File file = File(filepath);
try {
await _firebaseStorage
.ref(_firebaseStoragePath)
.putFile(file);
return true;
} catch (e) {
print('##MyAppFile## saveMyAppFileToCloudStorage Error: ' + e.toString()); //ERROR COMES FROM THIS LINE
return false;
}
return true;
}
I assume you're using the package ffmpeg_kit_flutter.
First, why it's not working: execute and executeAsync return FFmpegSession objects. The run of FFmpeg doesn't need to be finished for these methods to complete. In fact, the returned session object has methods like getState to monitor whether the run of FFmpeg has completed.
A good way to fix this: The documentation for executeAsync has a hint for what to do here.
Note that this method returns immediately and does not wait the execution to complete. You must use an FFmpegSessionCompleteCallback if you want to be notified about the result.
You can set a completion callback by passing a function to executeAsync. Here's the full function signature from the docs:
Future<FFmpegSession> executeAsync(
String command,
[FFmpegSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
StatisticsCallback? statisticsCallback = null]
)
FFmpegSessionCompleteCallback is just a function that accepts an FFmpegSession and returns nothing. You can provide your own.
void someCompletionFunction() {
setState(() {
currentMyAppFileFilename = currentMyAppFileFilename + '1.mp3';
});
}
await FFmpegKit.executeAsync(/*...parms...*/, someCompletionFunction);
Future vs callback: If you prefer to use Futures and async-await instead of callbacks, you'll need to create your own Future and update it in the callback. See Dart, how to create a future to return in your own functions? for an example.

How to apply pagination load more function using PageController

I am working on live video streaming application with flutter. Everything is working fine except load more function. i am loading first 10 records from server and when user reach to last video i want to load more 10 records. I am using page controller to control the video pages. how can i make load more function to work. Any help would be appreciated.
Below is my page controller class
class VideoListController {
/// Construction method
VideoListController();
/// Snap to slide to realize page turning
void setPageContrller(PageController pageController) {
pageController.addListener(() {
int pageIndex = pageController.page.round();
_HomePageState home = _HomePageState();
if(pageIndex==home.videoDataList.length)
{
home.loadMore();
print("TAG loading more now");
}
var p = pageController.page;
if (p % 1 == 0) {
int target = p ~/ 1;
if (index.value == target) return;
//Play the current one, pause the others
var oldIndex = index.value;
var newIndex = target;
playerOfIndex(oldIndex).seekTo(0);
playerOfIndex(oldIndex).pause();
playerOfIndex(newIndex).start();
// carry out
index.value = target;
}
});
}
//Get specified indexçš„player
FijkPlayer playerOfIndex(int index) => playerList[index];
/// Total number of videos
int get videoCount => playerList.length;
/// Continue to add videos behind the current list and preload the cover
addVideoInfo(List<VideoModel> list) {
for (var info in list) {
playerList.add(
FijkPlayer()
..setDataSource(
Glob.ITEM_BASE_URL + info.post_video,
autoPlay: playerList.length == 0,
showCover: true,
)
..setLoop(0),
);
}
}
/// initialization
init(PageController pageController, List<VideoModel> initialList) {
addVideoInfo(initialList);
setPageContrller(pageController);
}
/// Current video sequence number
ValueNotifier<int> index = ValueNotifier<int>(0);
/// Video list
List<FijkPlayer> playerList = [];
///
FijkPlayer get currentPlayer => playerList[index.value];
bool get isPlaying => currentPlayer.state == FijkState.started;
/// Destroy all
void dispose() {
// Destroy all
for (var player in playerList) {
player.dispose();
}
playerList = [];
}
}
Below is load more function
Future<List<VideoModel>> loadMore() async {
Video menu = await getVideos();
if (menu.status == true) {
print("TAG res success is true " + menu.message);
setState(() {
videoDataList.addAll(menu.data);
start=videoDataList.length.toString();
print("TAG start " + start);
});
_videoListController.addVideoInfo(menu.data);
}
else {
print("No Data Found Paras");
}
return videoDataList;
}
Future<Video> getVideos() {
String data_type="application/x-www-form-urlencoded";
Map<String,String> headers = new Map();
headers['Content-Type'] = data_type;
return _netUtil.post(Glob.POST_LIST, body: {"count": count, "start": start,"type": type, "my_user_id": my_user_id},headers: headers).then((dynamic obj)
{
var results;
bool success = obj["status"];
print("TAG success =$success");
if (success == true)
results = Video.fromJson(obj);
else
results = Video.fromJsondata(obj);
return results;
});
}
Any help would be appreciated.
You're checking in the wrong way. You're actually checking the pageIndex value with the list size. The problem with that is index starts from 0 while length from 1 so pageIndex is never gonna match home.videoDataList.length. You have to check with home.videoDataList.length - 1
if(pageIndex == home.videoDataList.length - 1)
{
home.loadMore();
print("TAG loading more now");
}

In angular dart is there a way to break early from a "foreach" loop

I saw that this is already answered for javascript but is there a way to break out of an forEach loop in angular dart.
bool hasValue() {
bool result = false;
periods.forEach((item) {
if (item.hasValue()) {
result = true;
//PENDING...Break out of loop early
}
});
return result;
}
As far as I know, you cannot break forEach loop.
You can try this code instead:
for(var item in items) {
final value = item['unit_value'];
if (value.isNotEmpty) {
break;
}
}

Collection find method doesn't work on Angular 2 recursive function

I'm developing Angular2 with Meteor.
When I make a little component with a recursive function, it has some weird error.
Here is my part of codes.
Not recursive - return a result
ngOnInit() {
//this.current_canvas return the right results
this.current_canvas = this.get_canvase(1);
}
get_canvase(which_canvas): Canvas[] {
if (!isNaN(which_canvas)) {
this.current_canvas_id = which_canvas;
return CanvasContents.find().map((messages: Canvas[]) => { return messages; })[0].content;
return '';
} else if(which_canvas == 'most-recent') {
this.get_canvase(1);
}
}
Recursive - Don't return a result
ngOnInit() {
//this.current_canvas Goes to NUll
this.current_canvas = this.get_canvase('most-recent');
}
get_canvase(which_canvas): Canvas[] {
if (!isNaN(which_canvas)) {
this.current_canvas_id = which_canvas;
console.log('this.current_canvas_id : ' + this.current_canvas_id);
return CanvasContents.find().map((messages: Canvas[]) => { return messages; })[0].content;
return '';
} else if(which_canvas == 'most-recent') {
this.get_canvase(1);
}
}
Have I used a wrong syntax? or is it on wrong Angular2 state to get right result?

How to pass a test if expect fails

I have this code
it('This should pass anyway', function (done) {
testObj.testIt(regStr);
});
testObj
this.testIt = function (regStr) {
selector.count().then(function (orgCount) {
for (var curr = 0; curr < count; curr++) {
checkField(curr, regStr);
}
});
};
function checkField(curr, regStr) {
selector.get(curr).all(by.tagName('li')).get(0).getInnerHtml().then(function (text) {
expect(text).to.match(regStr, curr + '#ERR');
});
}
If one of these expects get a failure, test fails. How can i handle this? I mean - can i somehow count passed and failed expect()ations and return it? or, at least, dont let test break on first error.
I've tried try-catch, but nothing good happened.
it('This should pass anyway', function (done) {
try {
testObj.testIt(regStr);
} catch (e) {
console.log('#err' + e);
}
});
And then i wanted to use done(), but havent found any examples to do the similar. Can u please help me?
Sry for my english
UPD
You can return either null or a string from checkField(), join them up, and expect the array to be empty:
this.testIt = function (regStr) {
selector.count().then(function (orgCount) {
var errors = [];
for (var curr = 0; curr < orgCount; curr++) {
var e = checkField(curr, regStr);
if (e) { errors.push(e); }
}
assert.equal(0, errors.length, errors);
});
};
A cleaner approach would be to use map() to collect the data into an array:
var data = selector.map(function (elm) {
return elm.element(by.tagName('li')).getText();
});
expect(data).toEqual(["test1", "test2", "test3"]);