问:
JSON Post to Node Server with Angular2 returns 404 URL not found
I'am using Angular2 to submit a POST Request to node Application/Server which is running on localhost:4000. But I keep getting 404 Error - Page not found.
The Node Sever/Application is running and I can test it via Postman...
I get Response as expected. just via Angular2 App is doesn't work.

Ang2 Code:

```<code>import { Component, OnInit } from '@angular/core';
import { MdRadioModule, MdButtonModule } from '@angular/material';
import { Http, Headers } from '@angular/http';
import { FormControl, FormGroup, FormBuilder } from '@angular/forms';

@Component({
   selector: 'app-signin',
   templateUrl: './login.component.html',
   styleUrls: ['./login.component.css']
})

export class LoginComponent implements OnInit {
   form: FormGroup;
   name = new FormControl();
   constructor(private http: Http, private fbuilder:FormBuilder) { }
   ngOnInit() {}

   login(mail:string, pass:string) {
      let headers = new Headers();
      let EMAIL_REGEXP = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/i;

      this.form = this.fbuilder.group({
          email: mail,
          password: pass
      });

      let formObj = this.form.getRawValue();
      let serializedForm = JSON.stringify(formObj);

      console.log( 'formObj: ' + formObj + '\n'
            + 'this.form: ' + this.form + '\n'
            + 'serializedForm: ' + serializedForm);

      if (!EMAIL_REGEXP.test(mail)) {
         return false;
      } else if (pass === '') {
         return false;
      } else {
        alert('Works!: ' + mail + 'pass: ' + pass);

        headers.append('Content-Type', 'application/json');

        this.http.post('http://localhost:4000/auth/sign_in', serializedForm, { headers })
            .subscribe(
                data => console.log('success!', data),
                error => console.error('Error caused by: ' + error)
            )

       }

    }

}
</code>```

The View:

```<code><section class="section--center" style="background-color:#fff;
                   margin:0 auto !important; box-shadow: 0 0 2px 0 #000000; height:auto; min-height:90%;">
    <div class="login-form" layout="row" layout-align="space-around" layout-padding="layout-padding">
        <md-card class="card">
            <div md-toolbar>
                <div class="md-toolbar-tools">
                    <h2><span>Login Form</span></h2>
                </div>
            </div md-toolbar>
            <form #form="ngForm" method="POST">
                <div style="padding:10px 0 10px 20px;">
                    <md-input-container>
                        <label>email:</label>
                        <input mdInput name="email" [(ngModel)]="email" #inputMail required
                            pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$">
                              <md-error>
                                   This field is required
                              </md-error>
                    </md-input-container>
                </div>
                <div style="padding:10px 0 10px 20px;">
                    <md-input-container>
                        <label>password:</label>
                        <input mdInput name="password [(ngModel)]="password" #inputPass required="" md-maxlength="16">
                        <md-error>
                            This field is required
                        </md-error>
                    </md-input-container>
                </div>
                <br>
                <div class="button-row">
                    <button class="submit" md-button (click)="login(inputMail.value, inputPass.value)">Add</button>
                </div>
            </form>
        </md-card>

    </div>

</section>
</code>```

Node:
'use strict';

```<code>    var mongoose = require('mongoose');
    var jwt = require('jsonwebtoken');
    var bcrypt = require('bcrypt');
    var User = mongoose.model('User');
    //mongoose.Promise = global.Promise;

    let mailer = require("nodemailer");
    let smtpTransport = require('nodemailer-smtp-transport');

   exports.sign_in = function (req, res) {
        User.findOne({
            email: req.body.email
        }, function (err, user) {
            if (err) throw err;
            if (!user || !user.comparePassword(req.body.password)) {
                return res.status(401).json({ message: 'Authentication failed. Invalid user or password.' });
            }
            return res.json(
                {
                    token: jwt.sign(
                        {
                            email: user.email,
                            fullName: user.fullName,
                            _id: user._id
                        },
                        'RESTFULAPIs'
                    )
                }
            );
        });
    };
</code>```

Node - server.js:

```<code>    let express = require('express');
let bodyParser = require('body-parser');
let path = require('path');
let app = express();
let router = express.Router();

// DB Schema and User Schema
let Task = require('./public/js/_nodeTodos/todoListModel');
let User = require('./userDbModel');

// Routing Paths
let routes = require('./public/js/_nodeTodos/todoListRoutes');

// Mongo DB
let mongoose = require('mongoose');

// WebToken
let jsonwebtoken = require("jsonwebtoken");

// Server Port
let port = process.env.PORT || 4000;

mongoose.Promise = global.Promise;
// Connecting to "Tododb" Database
mongoose.connect('mongodb://localhost/Tododb');

// Add headers
app.use(function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4000');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    res.setHeader('Access-Control-Allow-Credentials', true);
    next();
});
app.use('/scripts', express.static(__dirname + '/node_modules/angular-utf8-base64/'));
app.use('/assets', express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

app.use(function (req, res, next) {
    if (req.headers && req.headers.authorization && req.headers.authorization.split(' ')[0] === 'JWT') {
        jsonwebtoken.verify(req.headers.authorization.split(' ')[1], 'RESTFULAPIs', function (err, decode) {
            if (err) req.user = undefined;
            req.user = decode;
            next();
        });
    } else {
        req.user = undefined;
        next();
    }
});

//let routes = require('./public/js/_nodeTodos/todoListRoutes');
routes(app);

app.use('/', function (req, res, next) {
    console.log('Request Url:' + req.url);
    next();
});

app.get('/apiPortal', function(req, res) {
    //res.render('index');
    console.log('The EndPoint: ' + req.url);
    res.sendFile('index.htm', { root: __dirname + "/" } );
});

app.listen(port);
</code>```

Any Idea what could be the reason pls.?

答:
This error come when your pre flight request failed.

In your app backend(probably in app.js) set the

Access-Control-Allow-Origin

to your front end or * for every request.
This will allow your front end request.

Body:
I'am using Angular2 to submit a POST Request to node Application/Server which is running on localhost:4000. But I keep getting 404 Error - Page not found.
The Node Sever/Application is running and I can test it via Postman...
I get Response as expected. just via Angular2 App is doesn't work.

Ang2 Code:

import { Component, OnInit } from '@angular/core';
import { MdRadioModule, MdButtonModule } from '@angular/material';
import { Http, Headers } from '@angular/http';
import { FormControl, FormGroup, FormBuilder } from '@angular/forms';

@Component({
   selector: 'app-signin',
   templateUrl: './login.component.html',
   styleUrls: ['./login.component.css']
})

export class LoginComponent implements OnInit {
   form: FormGroup;
   name = new FormControl();
   constructor(private http: Http, private fbuilder:FormBuilder) { }
   ngOnInit() {}

   login(mail:string, pass:string) {
      let headers = new Headers();
      let EMAIL_REGEXP = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/i;

      this.form = this.fbuilder.group({
          email: mail,
          password: pass
      });

      let formObj = this.form.getRawValue();
      let serializedForm = JSON.stringify(formObj);

      console.log( 'formObj: ' + formObj + '\n'
            + 'this.form: ' + this.form + '\n'
            + 'serializedForm: ' + serializedForm);

      if (!EMAIL_REGEXP.test(mail)) {
         return false;
      } else if (pass === '') {
         return false;
      } else {
        alert('Works!: ' + mail + 'pass: ' + pass);

        headers.append('Content-Type', 'application/json');

        this.http.post('http://localhost:4000/auth/sign_in', serializedForm, { headers })
            .subscribe(
                data => console.log('success!', data),
                error => console.error('Error caused by: ' + error)
            )

       }

    }

}

The View:

        <md-card class="card">

Login Form

            <form #form="ngForm" method="POST">

                    <md-input-container>
                        email:
                        <input mdInput name="email" [(ngModel)]="email" #inputMail required
                            pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$">
                              <md-error>
                                   This field is required
                              </md-error>
                    </md-input-container>

                    <md-input-container>
                        password:
                        <input mdInput name="password [(ngModel)]="password" #inputPass required="" md-maxlength="16">
                        <md-error>
                            This field is required
                        </md-error>
                    </md-input-container>

                    <button class="submit" md-button (click)="login(inputMail.value, inputPass.value)">Add</button>

            </form>
        </md-card>

Node:
'use strict';

    var mongoose = require('mongoose');
    var jwt = require('jsonwebtoken');
    var bcrypt = require('bcrypt');
    var User = mongoose.model('User');
    //mongoose.Promise = global.Promise;

    let mailer = require("nodemailer");
    let smtpTransport = require('nodemailer-smtp-transport');

   exports.sign_in = function (req, res) {
        User.findOne({
            email: req.body.email
        }, function (err, user) {
            if (err) throw err;
            if (!user || !user.comparePassword(req.body.password)) {
                return res.status(401).json({ message: 'Authentication failed. Invalid user or password.' });
            }
            return res.json(
                {
                    token: jwt.sign(
                        {
                            email: user.email,
                            fullName: user.fullName,
                            _id: user._id
                        },
                        'RESTFULAPIs'
                    )
                }
            );
        });
    };

Node - server.js:

    let express = require('express');
let bodyParser = require('body-parser');
let path = require('path');
let app = express();
let router = express.Router();

// DB Schema and User Schema
let Task = require('./public/js/_nodeTodos/todoListModel');
let User = require('./userDbModel');

// Routing Paths
let routes = require('./public/js/_nodeTodos/todoListRoutes');

// Mongo DB
let mongoose = require('mongoose');

// WebToken
let jsonwebtoken = require("jsonwebtoken");

// Server Port
let port = process.env.PORT || 4000;

mongoose.Promise = global.Promise;
// Connecting to "Tododb" Database
mongoose.connect('mongodb://localhost/Tododb');

// Add headers
app.use(function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4000');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    res.setHeader('Access-Control-Allow-Credentials', true);
    next();
});
app.use('/scripts', express.static(__dirname + '/node_modules/angular-utf8-base64/'));
app.use('/assets', express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

app.use(function (req, res, next) {
    if (req.headers && req.headers.authorization && req.headers.authorization.split(' ')[0] === 'JWT') {
        jsonwebtoken.verify(req.headers.authorization.split(' ')[1], 'RESTFULAPIs', function (err, decode) {
            if (err) req.user = undefined;
            req.user = decode;
            next();
        });
    } else {
        req.user = undefined;
        next();
    }
});

//let routes = require('./public/js/_nodeTodos/todoListRoutes');
routes(app);

app.use('/', function (req, res, next) {
    console.log('Request Url:' + req.url);
    next();
});

app.get('/apiPortal', function(req, res) {
    //res.render('index');
    console.log('The EndPoint: ' + req.url);
    res.sendFile('index.htm', { root: __dirname + "/" } );
});

app.listen(port);

Any Idea what could be the reason pls.?


来源: stackexchange

问:
How to make a foreach of an object in javascript?
I am currently building a mashup in Qlik Sense in JavaScript and jQuery. I have made some data selection and I have put them in a variable object :

```<code>var CurrentSelec = app1.selectionState().selections;
console.log(CurrentSelec);`
console.log(typeof CurrentSelec);
</code>```

This is what I get on my browser console :

I'm trying to show the qSelected value in a Foreach :

I have tried with Javascript :

```<code>for(var index in CurrentSelec) {
    console.log(index.qSelected);
}
</code>```

I have tried with jQuery:

```<code>$.each(CurrentSelec, function(i, index) {
  console.log(index.qSelected)
});
</code>```

But my browser console do not show the log of my foreach.

Do you know how to properly make a foreach of an object and show its content on a browser console, please ?

Regards.

答:
```<code>for (var index in CurrentSelec[0]) {
 console.log(index.qSelected);
}
</code>```

try this

ContentLicense: CC BY-SA 3.0

Body:
I am currently building a mashup in Qlik Sense in JavaScript and jQuery. I have made some data selection and I have put them in a variable object :

var CurrentSelec = app1.selectionState().selections;
console.log(CurrentSelec);`
console.log(typeof CurrentSelec);

This is what I get on my browser console :

I'm trying to show the qSelected value in a Foreach :

I have tried with Javascript :

for(var index in CurrentSelec) {
    console.log(index.qSelected);
}

I have tried with jQuery:

$.each(CurrentSelec, function(i, index) {
  console.log(index.qSelected)
});

But my browser console do not show the log of my foreach.

Do you know how to properly make a foreach of an object and show its content on a browser console, please ?

Regards.

Body:
for (var index in CurrentSelec[0]) {
 console.log(index.qSelected);
}

try this


问:
How to change UIDocumentInteractionController Done button text and background color
How to change the background color and text color of done button? Is there a way that I can change the navigationbar color and navigation bar title color and bottom bar color also? Attached screenshot for reference:

答:
I solved it. Here is the code working for me perfectly:</p>

```<code>func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
    UINavigationBar.appearance().barTintColor = Colors.redColor()
    UINavigationBar.appearance().tintColor = UIColor.white
    UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : UIColor.white, NSFontAttributeName: UIFont.systemFont(ofSize: 14, weight: UIFontWeightBold)]
    return self
}
</code>```

Body:
I solved it. Here is the code working for me perfectly:

func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
    UINavigationBar.appearance().barTintColor = Colors.redColor()
    UINavigationBar.appearance().tintColor = UIColor.white
    UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : UIColor.white, NSFontAttributeName: UIFont.systemFont(ofSize: 14, weight: UIFontWeightBold)]
    return self
}


问:
How do i exit the program when i type a specific word, in my case "end"?
I'm having a problem. I'm currently doing a school project for a ChatBot. This is a game section for the chatbot. It's a word scramble game. I can enter the wrong answer and the program would prompt me to retype the answer. But, if I type the correct answer, the program just stops there, the program didn't stop.

What I would like to do is to repeat the code, like keeping playing the game, until I type the word "end", but I don't know how to implement it. Also, most of the words kept repeating. For example, the word [animal] would usually be scrambled into [anialm].

So I would like to get some help on improving the code too. Thank you very much!! I am still a Year 1 who just started learning to program.

```<code>public static void main(String[] args) {
        Scanner userinput = new Scanner(System.in);
        String guess = "";
        String scramble = "";
        String[] questions = {"animal", "duck", "dinosaur", "butterfly", "dog", "horse", "cow", "cat", "elephant", "crocodile", "alligator"};
        char charArr[] = null;
        String wordToGuess = questions[new Random().nextInt(questions.length)];// questions[0]

        for (int a = 0; a < wordToGuess.length(); a++) {
            charArr = wordToGuess.toCharArray();  //0a 1n 2i 3m 4a 5l 6s
            //generating a random number from the length of word to guess. Example: Animal, generated no = "1"
            int rdm = new Random().nextInt(charArr.length);
            //shuffling the words
            char temp = charArr[a];     //charArr[0] is the letter "A" which is moved to temp
            charArr[a] = charArr[rdm];  //A is then moved to charArr[rdm] which is index 1, so the word is currently "AAimals'
            charArr[rdm] = temp;        //charArr[1] contains n which is then moved to temmp, which is 0, becoming nAimal
        }
        scramble = new String(charArr);
        System.out.println("Your word is: " + scramble);

        do {
            while (!guess.equals(wordToGuess)) {
                System.out.print(">>> ");
                guess = userinput.nextLine();
                if (!guess.equals(wordToGuess)) {
                    System.out.print(">>> ");
                    System.out.println("Please try again!");
                } else {
                    System.out.println(">>> Great Job getting the answer!");
                }
            }
        }while (!guess.equalsIgnoreCase("end"));
    }
}
</code>```

答:
I think that the first thing to do is to look to restructure your code, this will make it easier to debug.

I would say that your code is basically asking to be separated into two man parts: one to run the game and one to contain the data:

```<code>public class Anagram {

    private String original= null;
    private String scrambled = null;

    public Anagram(String originalWord) {
        this.original = originalWord;
        this.scrambled = scramble(originalWord);
    }

    private String scramble(String original) {
        //scramble logic here
        return null;//your scrambled String
    }

    public boolean guess(String guess) {
        return original.equals(guess);
    }

}
</code>```

Then we will have much less to worry about and our running loop basically becomes like:

```<code>Anagram anagram = new Anagram(wordToGuess);

String input = null;
while (true) {
    System.out.print(">>> ");
    input = userinput.nextLine();
    if (input.equalsIgnoreCase("end")) {
        System.out.println("Unlucky, please come back again");
        System.exit(0);
    }

    if (anagram.guess(input)) {
        System.out.println(">>> Great Job getting the answer!");
        System.exit(0);
    }
    else {
        System.out.print(">>> ");
        System.out.println("Incorrrect, please try again!");
    }
}
</code>```

This uses while(true) which could easily be replaced with some other kind of loop.

Additionally you would probably benefit by extracting your set up code to another method.

Body:
I'm having a problem. I'm currently doing a school project for a ChatBot. This is a game section for the chatbot. It's a word scramble game. I can enter the wrong answer and the program would prompt me to retype the answer. But, if I type the correct answer, the program just stops there, the program didn't stop.

What I would like to do is to repeat the code, like keeping playing the game, until I type the word "end", but I don't know how to implement it. Also, most of the words kept repeating. For example, the word [animal] would usually be scrambled into [anialm].

So I would like to get some help on improving the code too. Thank you very much!! I am still a Year 1 who just started learning to program.

public static void main(String[] args) {
        Scanner userinput = new Scanner(System.in);
        String guess = "";
        String scramble = "";
        String[] questions = {"animal", "duck", "dinosaur", "butterfly", "dog", "horse", "cow", "cat", "elephant", "crocodile", "alligator"};
        char charArr[] = null;
        String wordToGuess = questions[new Random().nextInt(questions.length)];// questions[0]

        for (int a = 0; a < wordToGuess.length(); a++) {
            charArr = wordToGuess.toCharArray();  //0a 1n 2i 3m 4a 5l 6s
            //generating a random number from the length of word to guess. Example: Animal, generated no = "1"
            int rdm = new Random().nextInt(charArr.length);
            //shuffling the words
            char temp = charArr[a];     //charArr[0] is the letter "A" which is moved to temp
            charArr[a] = charArr[rdm];  //A is then moved to charArr[rdm] which is index 1, so the word is currently "AAimals'
            charArr[rdm] = temp;        //charArr[1] contains n which is then moved to temmp, which is 0, becoming nAimal
        }
        scramble = new String(charArr);
        System.out.println("Your word is: " + scramble);

        do {
            while (!guess.equals(wordToGuess)) {
                System.out.print(">>> ");
                guess = userinput.nextLine();
                if (!guess.equals(wordToGuess)) {
                    System.out.print(">>> ");
                    System.out.println("Please try again!");
                } else {
                    System.out.println(">>> Great Job getting the answer!");
                }
            }
        }while (!guess.equalsIgnoreCase("end"));
    }
}

Body:
I think that the first thing to do is to look to restructure your code, this will make it easier to debug.

I would say that your code is basically asking to be separated into two man parts: one to run the game and one to contain the data:

public class Anagram {

    private String original= null;
    private String scrambled = null;

    public Anagram(String originalWord) {
        this.original = originalWord;
        this.scrambled = scramble(originalWord);
    }

    private String scramble(String original) {
        //scramble logic here
        return null;//your scrambled String
    }

    public boolean guess(String guess) {
        return original.equals(guess);
    }

}

Then we will have much less to worry about and our running loop basically becomes like:

Anagram anagram = new Anagram(wordToGuess);

String input = null;
while (true) {
    System.out.print(">>> ");
    input = userinput.nextLine();
    if (input.equalsIgnoreCase("end")) {
        System.out.println("Unlucky, please come back again");
        System.exit(0);
    }

    if (anagram.guess(input)) {
        System.out.println(">>> Great Job getting the answer!");
        System.exit(0);
    }
    else {
        System.out.print(">>> ");
        System.out.println("Incorrrect, please try again!");
    }
}

This uses while(true) which could easily be replaced with some other kind of loop.

Additionally you would probably benefit by extracting your set up code to another method.


问:
Android iBeacon App not working in the background
I have developed Android app to  detect the beacon if the customer is near to 1 mt distance . I am using Android Beacon Library to develop the application.When we are in foreground the I get the notification but as soon as the application goes into background .. notification stooped working . Could you help me where am I wrong ?
Below is the code for BeaconApp and MainActivity.

BeaconApp.java

```<code>public class BeaconApp extends Application implements BootstrapNotifier {
    private static final String TAG = "BeaconApp";
    private RegionBootstrap regionBootstrap;
    private Region allbeaconsregions;
    private BackgroundPowerSaver bgSaver;
    BeaconManager beaconManager;
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "App started up");
        // To detect proprietary beacons, you must add a line likebelowcorresponding to your beacon
        // type.  Do a web search for "setBeaconLayout" to get the proper expression.
        // beaconManager.getBeaconParsers().add(new BeaconParser().
        //        setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));

        // wake up the app when any beacon is seen (you can specify specific id filers in the parameters below)
        beaconManager = BeaconManager.getInstanceForApplication(this);
        Beacon.setHardwareEqualityEnforced(true);
        bgSaver = new BackgroundPowerSaver(this);
        beaconManager.getBeaconParsers().add(new BeaconParser().
                setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));

        allbeaconsregions = new Region("treewalker", null, null, null);
        regionBootstrap = new RegionBootstrap(this, allbeaconsregions);
        //beaconManager.bind(this);
    }

    @Override
    public void didDetermineStateForRegion(int arg0, Region arg1) {
        // Don't care
        Log.d(TAG, "Enter in  didDetermineStateForRegion call");
    }

    @Override
    public void didEnterRegion(Region arg0) {
        Log.d(TAG, "Got a didEnterRegion call");
        // This call to disable will make it so the activity below only gets launched the first time a beacon is seen (until the next time the app is launched)
        // if you want the Activity to launch every single time beacons come into view, remove this call.
        regionBootstrap.disable();
        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        // Important:  make sure to add android:launchMode="singleInstance" in the manifest
        // to keep multiple copies of this activity from getting created if the user has
        // already manually launched the app.
        this.startActivity(intent);

    }

    @Override
    public void didExitRegion(Region arg0) {
        // Don't care
        Log.d(TAG, "Enter in  didExitRegion call");
    }

}
</code>```

In MainActivity.java

```<code>public class MainActivity extends AppCompatActivity implements BeaconConsumer,RangeNotifier {
    protected static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBeaconManager = BeaconManager.getInstanceForApplication(this);
        Beacon.setHardwareEqualityEnforced(true);
        BackgroundPowerSaver bgSaver = new BackgroundPowerSaver(this);
        mBeaconManager.getBeaconParsers().add(new BeaconParser().
                setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
        mBeaconManager.bind(this);

    }

    private BeaconManager mBeaconManager;

    public void onResume() {
        super.onResume();
        mBeaconManager = BeaconManager.getInstanceForApplication(this.getApplicationContext());
        // Detect the main Eddystone-UID frame:
        mBeaconManager.getBeaconParsers().add(new BeaconParser().
                setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
        mBeaconManager.bind(this);
    }

   public void onBeaconServiceConnect() {

           try {
               mBeaconManager.startRangingBeaconsInRegion(new Region("treewalker", null, null, null));
               mBeaconManager.addRangeNotifier(this);
           }catch (RemoteException e){
               e.printStackTrace();
           }

   }

    @Override
    public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {

        if(beacons.size() > 0) {
            for (Beacon beacon : beacons) {
                if (beacon.getDistance() < 1.0) {
                    Log.d(TAG, "I see a beacon transmitting a : " +
                            " approximately " + beacon.getDistance() + " meters away.");

                    Log.d(TAG, "BEACON DATA : " +beacon.getBluetoothAddress()+":"+beacon.getBluetoothName()+":"+beacon.getId1());

                    showNotification("Treewalker","You are near beacon range");
                    Intent intent = new Intent(this,MainActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    this.startActivity(intent);

                }

            }
        }
    }

    public void showNotification(String title, String message) {
        Intent notifyIntent = new Intent(this, DashboardActivity.class);
        notifyIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivities(this, 0,
                new Intent[] { notifyIntent }, PendingIntent.FLAG_UPDATE_CURRENT);
        Notification notification = new Notification.Builder(this)
                .setSmallIcon(android.R.drawable.ic_dialog_info)
                .setContentTitle(title)
                .setContentText(message)
                .setAutoCancel(true)
                .setContentIntent(pendingIntent)
                .build();
        notification.defaults |= Notification.DEFAULT_SOUND;
        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(1, notification);
    }
    @Override
    public void onPause() {
        super.onPause();
        //mBeaconManager.unbind(this);
    }
}
</code>```

答:
The problem is that when your app goes to the background, the MainActivity will call onPause, and the code inside that method calls the mBeaconManager.unbind(this); method, which effectively stops beacon ranging.

If you want ranging to continue in the background, the easiest thing to do is move the following two lines:

```<code>mBeaconManager.startRangingBeaconsInRegion(new Region("treewalker", null, null, null));
mBeaconManager.addRangeNotifier(this);
</code>```

to the BeaconApp class' didDetermineStateForRegion method.  You'll also need to move the didRangeBeaconsInRegion and showNotification methods there, too.

Body:
I have developed Android app to  detect the beacon if the customer is near to 1 mt distance . I am using Android Beacon Library to develop the application.When we are in foreground the I get the notification but as soon as the application goes into background .. notification stooped working . Could you help me where am I wrong ?
Below is the code for BeaconApp and MainActivity.

BeaconApp.java

public class BeaconApp extends Application implements BootstrapNotifier {
    private static final String TAG = "BeaconApp";
    private RegionBootstrap regionBootstrap;
    private Region allbeaconsregions;
    private BackgroundPowerSaver bgSaver;
    BeaconManager beaconManager;
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "App started up");
        // To detect proprietary beacons, you must add a line likebelowcorresponding to your beacon
        // type.  Do a web search for "setBeaconLayout" to get the proper expression.
        // beaconManager.getBeaconParsers().add(new BeaconParser().
        //        setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));

        // wake up the app when any beacon is seen (you can specify specific id filers in the parameters below)
        beaconManager = BeaconManager.getInstanceForApplication(this);
        Beacon.setHardwareEqualityEnforced(true);
        bgSaver = new BackgroundPowerSaver(this);
        beaconManager.getBeaconParsers().add(new BeaconParser().
                setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));

        allbeaconsregions = new Region("treewalker", null, null, null);
        regionBootstrap = new RegionBootstrap(this, allbeaconsregions);
        //beaconManager.bind(this);
    }

    @Override
    public void didDetermineStateForRegion(int arg0, Region arg1) {
        // Don't care
        Log.d(TAG, "Enter in  didDetermineStateForRegion call");
    }

    @Override
    public void didEnterRegion(Region arg0) {
        Log.d(TAG, "Got a didEnterRegion call");
        // This call to disable will make it so the activity below only gets launched the first time a beacon is seen (until the next time the app is launched)
        // if you want the Activity to launch every single time beacons come into view, remove this call.
        regionBootstrap.disable();
        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        // Important:  make sure to add android:launchMode="singleInstance" in the manifest
        // to keep multiple copies of this activity from getting created if the user has
        // already manually launched the app.
        this.startActivity(intent);

    }

    @Override
    public void didExitRegion(Region arg0) {
        // Don't care
        Log.d(TAG, "Enter in  didExitRegion call");
    }

}

In MainActivity.java

public class MainActivity extends AppCompatActivity implements BeaconConsumer,RangeNotifier {
    protected static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBeaconManager = BeaconManager.getInstanceForApplication(this);
        Beacon.setHardwareEqualityEnforced(true);
        BackgroundPowerSaver bgSaver = new BackgroundPowerSaver(this);
        mBeaconManager.getBeaconParsers().add(new BeaconParser().
                setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
        mBeaconManager.bind(this);

    }

    private BeaconManager mBeaconManager;

    public void onResume() {
        super.onResume();
        mBeaconManager = BeaconManager.getInstanceForApplication(this.getApplicationContext());
        // Detect the main Eddystone-UID frame:
        mBeaconManager.getBeaconParsers().add(new BeaconParser().
                setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
        mBeaconManager.bind(this);
    }

   public void onBeaconServiceConnect() {

           try {
               mBeaconManager.startRangingBeaconsInRegion(new Region("treewalker", null, null, null));
               mBeaconManager.addRangeNotifier(this);
           }catch (RemoteException e){
               e.printStackTrace();
           }

   }

    @Override
    public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {

        if(beacons.size() > 0) {
            for (Beacon beacon : beacons) {
                if (beacon.getDistance() < 1.0) {
                    Log.d(TAG, "I see a beacon transmitting a : " +
                            " approximately " + beacon.getDistance() + " meters away.");

                    Log.d(TAG, "BEACON DATA : " +beacon.getBluetoothAddress()+":"+beacon.getBluetoothName()+":"+beacon.getId1());

                    showNotification("Treewalker","You are near beacon range");
                    Intent intent = new Intent(this,MainActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    this.startActivity(intent);

                }

            }
        }
    }

    public void showNotification(String title, String message) {
        Intent notifyIntent = new Intent(this, DashboardActivity.class);
        notifyIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivities(this, 0,
                new Intent[] { notifyIntent }, PendingIntent.FLAG_UPDATE_CURRENT);
        Notification notification = new Notification.Builder(this)
                .setSmallIcon(android.R.drawable.ic_dialog_info)
                .setContentTitle(title)
                .setContentText(message)
                .setAutoCancel(true)
                .setContentIntent(pendingIntent)
                .build();
        notification.defaults |= Notification.DEFAULT_SOUND;
        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(1, notification);
    }
    @Override
    public void onPause() {
        super.onPause();
        //mBeaconManager.unbind(this);
    }
}

Body:
The problem is that when your app goes to the background, the MainActivity will call onPause, and the code inside that method calls the mBeaconManager.unbind(this); method, which effectively stops beacon ranging.

If you want ranging to continue in the background, the easiest thing to do is move the following two lines:

mBeaconManager.startRangingBeaconsInRegion(new Region("treewalker", null, null, null));
mBeaconManager.addRangeNotifier(this);

to the BeaconApp class' didDetermineStateForRegion method.  You'll also need to move the didRangeBeaconsInRegion and showNotification methods there, too.


问:
Phoenix/Elixir - protocol Phoenix.Param not implemented for #PID<0.890.0>
In my Phoenix app I am using a Genserver (Paginator) to maintain state for pagination purposes.

I have this in my PageController:

```<code>def index(conn, params) do
  {page_entries, current_page} = case Map.get(params, "page_entries") do
                                  nil ->
                                    {:ok, page_entries} = Paginator.start_link()
                                    {page_entries, 1}
                                  page_entries ->
                                    {page_entries, Map.get(params, "current_page")}
                                 end
  # do some stuff
  render conn, "index.html", page_entries: page_entries, current_page: current_page
end
</code>```

In my template index.html.eex I have this link:

```<code>link "Next→", to: page_path(@conn, :index, page_entries: @page_entries, current_page: @current_page+1)
</code>```

But I get this error:

```<code>protocol Phoenix.Param not implemented for #PID<0.890.0>
</code>```

From the docs:

By default, Phoenix implements this protocol for integers, binaries, atoms, maps and structs.

How do I send the process id across pages through links? Is there any way to do it without the process data appearing in the query string?

答:
You should not pass PID across. PID is not a long-lived entity, it changes when the process crashes and is restarted by the supervisor, it differs amongst different nodes. Pass either name or an id instead.

GenServer.start_link/3 has an optional opts parameter, where one might pass a name:

```<code>GenServer.start_link(__MODULE__, [], name: __MODULE__)
</code>```

Later on, when you need to call this Paginator’s instance, just pass this name instead of PID:

```<code>GenServer.call(Paginator, {:blah, 42})
</code>```

Body:
In my Phoenix app I am using a Genserver (Paginator) to maintain state for pagination purposes.

I have this in my PageController:

def index(conn, params) do
  {page_entries, current_page} = case Map.get(params, "page_entries") do
                                  nil ->
                                    {:ok, page_entries} = Paginator.start_link()
                                    {page_entries, 1}
                                  page_entries ->
                                    {page_entries, Map.get(params, "current_page")}
                                 end
  # do some stuff
  render conn, "index.html", page_entries: page_entries, current_page: current_page
end

In my template index.html.eex I have this link:

link "Next→", to: page_path(@conn, :index, page_entries: @page_entries, current_page: @current_page+1)

But I get this error:

protocol Phoenix.Param not implemented for #PID<0.890.0>

From the docs:

By default, Phoenix implements this protocol for integers, binaries, atoms, maps and structs.

How do I send the process id across pages through links? Is there any way to do it without the process data appearing in the query string?

Body:
You should not pass PID across. PID is not a long-lived entity, it changes when the process crashes and is restarted by the supervisor, it differs amongst different nodes. Pass either name or an id instead.

GenServer.start_link/3 has an optional opts parameter, where one might pass a name:

GenServer.start_link(__MODULE__, [], name: __MODULE__)

Later on, when you need to call this Paginator’s instance, just pass this name instead of PID:

GenServer.call(Paginator, {:blah, 42})


问:
How to include zero-count results in query
I have these two tables:

Operators:

```<code>Id Nome
--+----
 1 JDOE
 2 RROE
 3 MMOE
</code>```

Calls:

```<code>Id CallDate OpId
--+--------+----
 1 20161228    2
 2 20161228    3
 3 20161228    2
 4 20161228    3
 5 20170104    1
 6 20170104    2
 7 20170104    1
</code>```

And this query:

```<code>SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON Operators.id = Calls.OpId
GROUP BY Calls.CallDate, Operators.id, Operators.Nome
HAVING Calls.CallDate=20170104;
</code>```

Which returns:

```<code>Id Nome CountCalls
--+----+----------
 1 JDOE          2
 2 RROE          1
</code>```

How can I make it return this, instead?

```<code>Id Nome CountCalls
--+----+----------
 1 JDOE          2
 2 RROE          1
 3 MMOE          0
</code>```

That is, how to include in any query also the zero results from main table which has no occurrence in left joined table, at least in the data slice defined by the query filtering criteria?

This is Access 2013.

I've read this answer but couldn't see how it is different from what I'm doing.

答:
Because you have a reference to Calls.CallDate in your HAVING clause, you are removing operators where there are no calls. If there were no calls, then CallDate would be NULL, and NULL=20170104 is not true, so these rows are excluded. You need to move this predicate to your join clause:

```<code>SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON (Operators.id = Calls.OpId AND Calls.CallDate=20170104)
GROUP BY Calls.CallDate, Operators.id, Operators.Nome;
</code>```

You also don't need to group by Calls.CallDate, since you only have one anyway, so you can just use:

```<code>SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON (Operators.id = Calls.OpId AND Calls.CallDate=20170104)
GROUP BY Operators.id, Operators.Nome;
</code>```

As an aside HAVING is the wrong operator. HAVING is for filtering aggregates, since you are not filtering an aggregate, you should simply use WHERE

```<code>SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON Operators.id = Calls.OpId
WHERE Calls.CallDate=20170104
GROUP BY Calls.CallDate, Operators.id, Operators.Nome;
</code>```

You would use HAVING if you wanted to fliter on CountCalls, e.g if you only wanted operators that had made more than 1 call you might use:

```<code>SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON Operators.id = Calls.OpId
WHERE Calls.CallDate=20170104
GROUP BY Calls.CallDate, Operators.id, Operators.Nome
HAVING Count(Calls.OpId) > 1;
</code>```

This would only return

```<code>Id Nome CountCalls
--+----+----------
 1 JDOE          2
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have these two tables:

Operators:

Id Nome
--+----
 1 JDOE
 2 RROE
 3 MMOE

Calls:

Id CallDate OpId
--+--------+----
 1 20161228    2
 2 20161228    3
 3 20161228    2
 4 20161228    3
 5 20170104    1
 6 20170104    2
 7 20170104    1

And this query:

SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON Operators.id = Calls.OpId
GROUP BY Calls.CallDate, Operators.id, Operators.Nome
HAVING Calls.CallDate=20170104;

Which returns:

Id Nome CountCalls
--+----+----------
 1 JDOE          2
 2 RROE          1

How can I make it return this, instead?

Id Nome CountCalls
--+----+----------
 1 JDOE          2
 2 RROE          1
 3 MMOE          0

That is, how to include in any query also the zero results from main table which has no occurrence in left joined table, at least in the data slice defined by the query filtering criteria?

This is Access 2013.

I've read this answer but couldn't see how it is different from what I'm doing.

Body:
Because you have a reference to Calls.CallDate in your HAVING clause, you are removing operators where there are no calls. If there were no calls, then CallDate would be NULL, and NULL=20170104 is not true, so these rows are excluded. You need to move this predicate to your join clause:

SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON (Operators.id = Calls.OpId AND Calls.CallDate=20170104)
GROUP BY Calls.CallDate, Operators.id, Operators.Nome;

You also don't need to group by Calls.CallDate, since you only have one anyway, so you can just use:

SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON (Operators.id = Calls.OpId AND Calls.CallDate=20170104)
GROUP BY Operators.id, Operators.Nome;

As an aside HAVING is the wrong operator. HAVING is for filtering aggregates, since you are not filtering an aggregate, you should simply use WHERE

SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON Operators.id = Calls.OpId
WHERE Calls.CallDate=20170104
GROUP BY Calls.CallDate, Operators.id, Operators.Nome;

You would use HAVING if you wanted to fliter on CountCalls, e.g if you only wanted operators that had made more than 1 call you might use:

SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON Operators.id = Calls.OpId
WHERE Calls.CallDate=20170104
GROUP BY Calls.CallDate, Operators.id, Operators.Nome
HAVING Count(Calls.OpId) > 1;

This would only return

Id Nome CountCalls
--+----+----------
 1 JDOE          2


问:
Handling 404 error problems in the WebView Delegate in iPhone sdk
I am working with WebView based application, in that I had a problem with http 404 errors when I tried to load an url. I just want to show an alert when this happens. Can you guys please suggest me that how to trigger it and is there are any delegate methods fired when this happens?. Please suggest.

Thanks in adv,
S.

答: You can not check the status code for UIWebView requests. I rarely use webviews to do requests and when I do I don't care what the status codes are. I usually use NSURLConnection or ASIHTTPRequest to do requests. If you have to know the status of the http request, then do it using an NSURLRequest object and set the delegate to receive the response status code.</p>

ContentLicense: CC BY-SA 2.5


问:
hiera() function and YAML hash lookups
How do I rewrite this YAML so it is more structured, then reference it in Puppet using hiera function?

Currently, I am working with a hieradata syntax that looks very flat and hard to read.

```<code>service::proxy::behind_reverse_proxy: true
service::proxy::proxy_timeout: 300
service::proxy::serverlist:
  - host1.fqdn
  - host2.fqdn
</code>```

And grabbed these in a params.pp file, for example

```<code>$behind_reverse_proxy = hiera('service::proxy::behind_reverse_proxy', 'False')
$serverlist = hiera('service::proxy::serverlist')
</code>```

I thought I could rewrite the YAML like so in an effort to make it more readable...

```<code>service::proxy:
  behind_reverse_proxy: true
  proxy_timeout: 300
  serverlist:
    - host1.fqdn
    - host2.fqdn
</code>```

And updated the params.pp file according to

Hiera Key.subkey syntax

interacting with structured data

```<code>$behind_reverse_proxy = hiera('service::proxy.behind_reverse_proxy', 'False')
$serverlist = hiera('service::proxy.serverlist')
</code>```

However upon puppet agent -t that resulted in

Error 400 on SERVER: Could not find data item service::proxy.serverlist in any Hiera data file and no default supplied

I think these are relevant

```<code>[user@server ~]$ facter -y | grep 'version'
facterversion: 2.4.4
puppetversion: 3.8.2
</code>```

答:
Following up on my comment about how you can access your restructured data:

```<code>service::proxy:
  behind_reverse_proxy: true
  proxy_timeout: 300
  serverlist:
    - host1.fqdn
    - host2.fqdn
</code>```

In your manifest, instead of this ...

<s>

```<code>$behind_reverse_proxy = hiera('service::proxy.behind_reverse_proxy', 'False')
$serverlist = hiera('service::proxy.serverlist')
</code>```

</s>

... you might do this:

```<code>$proxy_info = merge(
    { 'behind_reverse_proxy' => false, 'serverlist' => [] },
    hiera('service::proxy', {})
)
$behind_reverse_proxy = $proxy_info{'behind_reverse_proxy'}
$serverlist = $proxy_info{'serverlist'}
</code>```

The merge() function is not built-in, but rather comes from Puppet's (formerly PuppetLabs's) widely-used stdlib module.  There's a good chance that you are already using that module elsewhere, but even if not, it may be well worth your while to introduce it to your stack.

Title: hiera() function and YAML hash lookups

Body:
How do I rewrite this YAML so it is more structured, then reference it in Puppet using hiera function?

Currently, I am working with a hieradata syntax that looks very flat and hard to read.

service::proxy::behind_reverse_proxy: true
service::proxy::proxy_timeout: 300
service::proxy::serverlist:
  - host1.fqdn
  - host2.fqdn

And grabbed these in a params.pp file, for example

$behind_reverse_proxy = hiera('service::proxy::behind_reverse_proxy', 'False')
$serverlist = hiera('service::proxy::serverlist')

I thought I could rewrite the YAML like so in an effort to make it more readable...

service::proxy:
  behind_reverse_proxy: true
  proxy_timeout: 300
  serverlist:
    - host1.fqdn
    - host2.fqdn

And updated the params.pp file according to

Hiera Key.subkey syntax

interacting with structured data

$behind_reverse_proxy = hiera('service::proxy.behind_reverse_proxy', 'False')
$serverlist = hiera('service::proxy.serverlist')

However upon puppet agent -t that resulted in

Error 400 on SERVER: Could not find data item service::proxy.serverlist in any Hiera data file and no default supplied

I think these are relevant

[user@server ~]$ facter -y | grep 'version'
facterversion: 2.4.4
puppetversion: 3.8.2

Body:
Following up on my comment about how you can access your restructured data:

service::proxy:
  behind_reverse_proxy: true
  proxy_timeout: 300
  serverlist:
    - host1.fqdn
    - host2.fqdn

In your manifest, instead of this ...

<s>

$behind_reverse_proxy = hiera('service::proxy.behind_reverse_proxy', 'False')
$serverlist = hiera('service::proxy.serverlist')

</s>

... you might do this:

$proxy_info = merge(
    { 'behind_reverse_proxy' => false, 'serverlist' => [] },
    hiera('service::proxy', {})
)
$behind_reverse_proxy = $proxy_info{'behind_reverse_proxy'}
$serverlist = $proxy_info{'serverlist'}

The merge() function is not built-in, but rather comes from Puppet's (formerly PuppetLabs's) widely-used stdlib module.  There's a good chance that you are already using that module elsewhere, but even if not, it may be well worth your while to introduce it to your stack.


问:
angular2- Observable getting data out of order
So I am using a getAll to get all of a school's Virtual Hosts, which comes back as a list of ID's (id's of the Virtual Hosts). Then, in order to get the data of the Virtual Hosts, I must call another get on each of the ID's. I do this through a for loop like so--

```<code>    this.apiService.findAll("virtualhosts/deltest")
        .subscribe((data) => {
            this.data = data.docs[0]
            error => console.log(error)

            for (let i = 0; i < this.data.VirtualHosts.length; i++) {
                this.apiService.findVH(this.data.VirtualHosts[i])
                    .subscribe((data) => {
                        this.data = data.docs[0]
                        this.jsonData = this.jsonData.concat(this.data)

                    })
            }

        });
</code>```

The problem is, the apiService.findVH does not call the get in order of the ID's given by the apiService.findAll. Every time it gets called, it doesn't compute the ID's in order of the list (hence the indices of this.data.VirtualHosts[i] is different) How can I make the findVH (get call) call the indices in order?

答:
You can map an observable:

this
  .apiService
  .findAll("virtualhosts/deltest")
  .flatMap(data => this.apiService.findVH(data.VirtualHosts))
  .subscribe(/* whatever you want */)
;
```

Body:
So I am using a getAll to get all of a school's Virtual Hosts, which comes back as a list of ID's (id's of the Virtual Hosts). Then, in order to get the data of the Virtual Hosts, I must call another get on each of the ID's. I do this through a for loop like so--

    this.apiService.findAll("virtualhosts/deltest")
        .subscribe((data) => {
            this.data = data.docs[0]
            error => console.log(error)

            for (let i = 0; i < this.data.VirtualHosts.length; i++) {
                this.apiService.findVH(this.data.VirtualHosts[i])
                    .subscribe((data) => {
                        this.data = data.docs[0]
                        this.jsonData = this.jsonData.concat(this.data)

                    })
            }

        });

The problem is, the apiService.findVH does not call the get in order of the ID's given by the apiService.findAll. Every time it gets called, it doesn't compute the ID's in order of the list (hence the indices of this.data.VirtualHosts[i] is different) How can I make the findVH (get call) call the indices in order?


问:
How to import Microsoft Exchange data to SQL in SSIS
My boss gave me a job to rewrite an old piece of software into a SSIS package. I need the SSIS to:

access a specific mailbox on our Microsoft Exchange server

go through all the UNREAD emails and download attachments from them based on their file type

import the contents of these files (text readable through notepad) into an SQL table

import email subjects to another SQL table

I'm not sure if what I described above is available in a standard SSIS package (I doubt it) - maybe I'll need to download some libraries. So far I found this. Will it do the trick? If not, do you know any other way to achieve what I want using SSIS?

答:
The best way would be to use the Microsoft Exchange Webservices (=EWS) to download and work with all kind of attachments (here is an example).

However as this is a API you need to build some kind of middleware between MS Exchange and your SQL Server based on the EWS API. It could be something like:

```<code>//TODO: Replace these with your values
NetworkCredential exchangeAccessAccount = new NetworkCredential(@"UserName", @"Password", @"Domain");
Uri OutlookWebAccessUri = new Uri(@"[[Outlook Web Access Url]]/EWS/Exchange.asmx");
DateTime CalanderStart = new DateTime();
DateTime CalanderEnd = new DateTime();
int MaxItemsToReturn = 99999;

try
{
    #region create service binding

    // Create the service binding.
    ExchangeService esb = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
    esb.Credentials = exchangeAccessAccount;
    esb.Url = OutlookWebAccessUri;
    esb.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, Variables.UserDomainID.ToString());

    #endregion

    #region create CalendarView

    CalendarView calendarView = new CalendarView(CalanderStart, CalanderEnd, MaxItemsToReturn);
    calendarView.PropertySet = PropertySet.IdOnly;

    #endregion

    #region retrieve responce

    // Do the EWS Call...
    FindItemsResults<Appointment> findItemResponse = esb.FindAppointments(WellKnownFolderName.Calendar, calendarView);

    if (findItemResponse == null)
    {
        return;
    }

    #endregion

    #region load atendee data

    //get additional properties for each item returned by view, do this as view cannot return a lot of useful stuff like attendees
    ServiceResponseCollection<ServiceResponse> addProperties =
                esb.LoadPropertiesForItems(from Item item in findItemResponse select item,
                new PropertySet(
                        BasePropertySet.IdOnly,
                        AppointmentSchema.Resources,
                        AppointmentSchema.RequiredAttendees,
                        AppointmentSchema.OptionalAttendees,
                        AppointmentSchema.Subject,
                        AppointmentSchema.Start,
                        AppointmentSchema.End,
                        AppointmentSchema.IsCancelled
                        ));

    List<Appointment> additionalProperties = new List<Appointment>(addProperties.Count);

    if (addProperties != null)
    {
        foreach (ServiceResponse currentResponce in addProperties)
        {
           additionalProperties.Add(((Appointment)((GetItemResponse)currentResponce).Item));
        }
    }

    #endregion

    #region process appts

    Appointment currentAppointmentAddProps = null;

    foreach (Appointment currentAppointment in findItemResponse)
    {
        #region find additional properties for current Appointment

        currentAppointmentAddProps = additionalProperties.Find(delegate(Appointment arg)
              { return arg.Id == currentAppointment.Id; });

        #endregion

        //add data to output here
       OutputRecordSetBuffer.ActualEndDate = currentAppointmentAddProps.End;

    }

    #endregion
}
catch (Exception e)
{

}
</code>```

(more infos here)

Body:
The best way would be to use the Microsoft Exchange Webservices (=EWS) to download and work with all kind of attachments (here is an example).

However as this is a API you need to build some kind of middleware between MS Exchange and your SQL Server based on the EWS API. It could be something like:

//TODO: Replace these with your values
NetworkCredential exchangeAccessAccount = new NetworkCredential(@"UserName", @"Password", @"Domain");
Uri OutlookWebAccessUri = new Uri(@"[[Outlook Web Access Url]]/EWS/Exchange.asmx");
DateTime CalanderStart = new DateTime();
DateTime CalanderEnd = new DateTime();
int MaxItemsToReturn = 99999;

try
{
    #region create service binding

    // Create the service binding.
    ExchangeService esb = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
    esb.Credentials = exchangeAccessAccount;
    esb.Url = OutlookWebAccessUri;
    esb.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, Variables.UserDomainID.ToString());

    #endregion

    #region create CalendarView

    CalendarView calendarView = new CalendarView(CalanderStart, CalanderEnd, MaxItemsToReturn);
    calendarView.PropertySet = PropertySet.IdOnly;

    #endregion

    #region retrieve responce

    // Do the EWS Call...
    FindItemsResults<Appointment> findItemResponse = esb.FindAppointments(WellKnownFolderName.Calendar, calendarView);

    if (findItemResponse == null)
    {
        return;
    }

    #endregion

    #region load atendee data

    //get additional properties for each item returned by view, do this as view cannot return a lot of useful stuff like attendees
    ServiceResponseCollection<ServiceResponse> addProperties =
                esb.LoadPropertiesForItems(from Item item in findItemResponse select item,
                new PropertySet(
                        BasePropertySet.IdOnly,
                        AppointmentSchema.Resources,
                        AppointmentSchema.RequiredAttendees,
                        AppointmentSchema.OptionalAttendees,
                        AppointmentSchema.Subject,
                        AppointmentSchema.Start,
                        AppointmentSchema.End,
                        AppointmentSchema.IsCancelled
                        ));

    List<Appointment> additionalProperties = new List<Appointment>(addProperties.Count);

    if (addProperties != null)
    {
        foreach (ServiceResponse currentResponce in addProperties)
        {
           additionalProperties.Add(((Appointment)((GetItemResponse)currentResponce).Item));
        }
    }

    #endregion

    #region process appts

    Appointment currentAppointmentAddProps = null;

    foreach (Appointment currentAppointment in findItemResponse)
    {
        #region find additional properties for current Appointment

        currentAppointmentAddProps = additionalProperties.Find(delegate(Appointment arg)
              { return arg.Id == currentAppointment.Id; });

        #endregion

        //add data to output here
       OutputRecordSetBuffer.ActualEndDate = currentAppointmentAddProps.End;

    }

    #endregion
}
catch (Exception e)
{

}

(more infos here)


问:
Compare first and last value of row in Excel
I've put together a table to track the success of some SEO efforts. For each row I'd like to compare the starting value with the most recent value. We update this table each week, so it'd be great if it could dynamically reference the last non-blank space.

I tried this with Vlookup and Hlookup, but they both seem to only want to work vertically down the column.

This is what I've got now, but again, it's looking up values in the column instead of the row.

=VLOOKUP(C3+99,C5:C99,1)-C5

screenshot

I'm new to this, so I'm feeling pretty lost.

答:
Try VBA.  It is good to learn, especially if you are doing any technical work (SEO results can be tricky to interpret).

Here is an idea of the logic you could use for your first relatively simple VBA program:

Declare variables

Set up a loop.  Evaluate the value of each cell, and stop the loop when the contents are "".

Take the cell value and store it in a variable.

Compare the value of the dynamically-located last value with the first value (also stored in a variable).  You could do mathematical operations (find the difference, or % variance) or boolean operations (return true/false if the values = each other).


答:
Try this:

=C5-OFFSET(C5,0,COUNTA(C5:AAA5)-1)

CountA counts the number of non-empty spaces and offset retrieves a value from a specified number of cells away.

Title: Compare first and last value of row in Excel

Body:
I've put together a table to track the success of some SEO efforts. For each row I'd like to compare the starting value with the most recent value. We update this table each week, so it'd be great if it could dynamically reference the last non-blank space.

I tried this with Vlookup and Hlookup, but they both seem to only want to work vertically down the column.

This is what I've got now, but again, it's looking up values in the column instead of the row.

=VLOOKUP(C3+99,C5:C99,1)-C5

screenshot

I'm new to this, so I'm feeling pretty lost.


答:
Some info is missing here (and please rename to 'currentSelec) , but do:

```<code>CurrentSelec.forEach(function(item){
         console.log(item.qSelected)
    })
</code>```

What you did is iteration on the keys of the Array, and not the values.

Title: How to make a foreach of an object in javascript?

Body:
Some info is missing here (and please rename to 'currentSelec) , but do:

CurrentSelec.forEach(function(item){
         console.log(item.qSelected)
    })

What you did is iteration on the keys of the Array, and not the values.


问:
Create instance from same template as `this`?
Let's assume I've got a base class Base<T> and a lot of Sub1<T>, ... SubN<T> which are subclasses of Base. Base has some kind of member function foo and in foo I need to create a new instance. But I'd like to always create the new instance from the same child template, but with a different template argument (Sub1<T>::foo -> Sub1, Sub2<T>::foo -> Sub2, ...).

For ex. Sub1<float> a; auto b = a.foo(); so that b again would be a new Sub1<int> (even if foo is only overloaded on Base). Is this even possible? How would I do this?

答:
If you only want to implement the method in the Base class:

```<code>template <typename T, template <typename> class D>
struct Base
{
    template <typename U, typename... Args>
    D<U>* foo(Args&&... args)
    {
        return new D<U>(std::forward<Args>(args)...);
    }
};

template <typename T>
struct Derived1 : Base<T, Derived1>
{
    // Implementation specific to Derived1
};

template <typename T>
struct Derived2 : Base<T, Derived2>
{
    // Implementation specific to Derived2
};

int main()
{
    Derived1<float> d1_float;
    Derived2<float> d2_float;

    auto d1_int = d1_float.foo<int>(); // has type Derived1<int>
    auto d2_int = d2_float.foo<int>(); // has type Derived2<int>

    return 0;
}
</code>```

However, now Derived1 and Derived2 no longer share the same base class. So this is only useful if you use the base class to avoid code duplication and not for polymorphism.

Body:
If you only want to implement the method in the Base class:

template <typename T, template <typename> class D>
struct Base
{
    template <typename U, typename... Args>
    D<U>* foo(Args&&... args)
    {
        return new D<U>(std::forward<Args>(args)...);
    }
};

template <typename T>
struct Derived1 : Base<T, Derived1>
{
    // Implementation specific to Derived1
};

template <typename T>
struct Derived2 : Base<T, Derived2>
{
    // Implementation specific to Derived2
};

int main()
{
    Derived1<float> d1_float;
    Derived2<float> d2_float;

    auto d1_int = d1_float.foo<int>(); // has type Derived1<int>
    auto d2_int = d2_float.foo<int>(); // has type Derived2<int>

    return 0;
}

However, now Derived1 and Derived2 no longer share the same base class. So this is only useful if you use the base class to avoid code duplication and not for polymorphism.


答:
Try below query:

```<code>SELECT o.id, o.name, count(c.opid) as countcalls
FROM Operators o LEFT JOIN calls c ON o.id = c.opid AND c.calldate=20170104
GROUP BY c.calldate, o.id, o.name
ORDER BY o.id;
</code>```

Output:

```<code>+------+------+------------+
| id   | name | countcalls |
+------+------+------------+
|    1 | JDOE |          2 |
|    2 | RROE |          1 |
|    3 | MMOE |          0 |
+------+------+------------+
</code>```

Title: How to include zero-count results in query

Body:
Try below query:

SELECT o.id, o.name, count(c.opid) as countcalls
FROM Operators o LEFT JOIN calls c ON o.id = c.opid AND c.calldate=20170104
GROUP BY c.calldate, o.id, o.name
ORDER BY o.id;

Output:

+------+------+------------+
| id   | name | countcalls |
+------+------+------------+
|    1 | JDOE |          2 |
|    2 | RROE |          1 |
|    3 | MMOE |          0 |
+------+------+------------+


问:
Comparing elements in a list with its neighbours
I have a list of 29400 values in Python and I'm trying to check if each element of the list is larger than both the 2000 neighbors to its left and the 2000 neighbors to its right. If the element is larger than its 4000 neighbors, I want to retrieve the index of the element. If there aren't 2000 neighbors to the right I just want to compare it with future elements until I reach the end of the list, and vice versa if there aren't 2000 values to the left.

```<code>def find_peaks(t):
prev = []
future = []
peak_index = []
for i in range(len(t)-2000): # compare element with previous values
    for j in range(1,2001):
        if t[i]<t[i+j]:
            prev.append(False)
            break
        if j==2000:
            if t[i]<t[i+j]:
                prev.append(False)
                break
            prev.append(True)

for i in range(1999,len(t)-1): # compare element with future values
    for j in range(1,2001):
        if t[i]<t[i-j]:
            future.append(False)
            break
        if j==2000:
            if t[i]<t[i-j]:
                future.append(False)
                break
            future.append(True)
future = future[::-1] # reverse list
for i in range(0,len(prev)-1):
    if prev[i] == True:
        if prev[i] == True:
            peak_index.append(i)
</code>```

Does anyone know of any better ways to go about this? I was having trouble comparing elements near the end and the beginning of the list- If there aren't 2000 elements left in the list for me to compare with, then the list wraps around to the beginning of the list, which isn't something I want.

答:
A naive, iterative version would be to go through each element and do look behind/ahead a certain number of times to see if there are values larger than it, and if not consider it a pick:

```<code>def find_peaks(data, span=2000):
    peaks = []
    for i, value in enumerate(data):
        peak = False  # start with the assumed non-peak
        for j in range(max(0, i - 1), max(0, i - span - 1), -1):  # look behind
            peak = value > data[j]  # check if our value is larger than the selected neighbor
            if not peak:  # not a peak, break away
                break
        if peak:  # look behind passed, look ahead:
            for j in range(i + 1, min(i + span + 1, len(data))):
                if value <= data[j]:  # look ahead failed, break away
                    peak = False
                    break
            if peak:  # if look ahead passed...
                peaks.append(i)  # add it to our peaks list
    return peaks
</code>```

This is the most performant way to do it with look ahead/behind as it breaks away immediately when a condition is not met instead of checking every element with every element.

If you want to count in the neighbors that are of the same value when calculating a peak (so your current peak candidate is the same) you can use peak = value >= data[j] in the look behind and if value < data[j] in the look ahead portions.

Body:
I have a list of 29400 values in Python and I'm trying to check if each element of the list is larger than both the 2000 neighbors to its left and the 2000 neighbors to its right. If the element is larger than its 4000 neighbors, I want to retrieve the index of the element. If there aren't 2000 neighbors to the right I just want to compare it with future elements until I reach the end of the list, and vice versa if there aren't 2000 values to the left.

def find_peaks(t):
prev = []
future = []
peak_index = []
for i in range(len(t)-2000): # compare element with previous values
    for j in range(1,2001):
        if t[i]<t[i+j]:
            prev.append(False)
            break
        if j==2000:
            if t[i]<t[i+j]:
                prev.append(False)
                break
            prev.append(True)

for i in range(1999,len(t)-1): # compare element with future values
    for j in range(1,2001):
        if t[i]<t[i-j]:
            future.append(False)
            break
        if j==2000:
            if t[i]<t[i-j]:
                future.append(False)
                break
            future.append(True)
future = future[::-1] # reverse list
for i in range(0,len(prev)-1):
    if prev[i] == True:
        if prev[i] == True:
            peak_index.append(i)

Does anyone know of any better ways to go about this? I was having trouble comparing elements near the end and the beginning of the list- If there aren't 2000 elements left in the list for me to compare with, then the list wraps around to the beginning of the list, which isn't something I want.

Body:
A naive, iterative version would be to go through each element and do look behind/ahead a certain number of times to see if there are values larger than it, and if not consider it a pick:

def find_peaks(data, span=2000):
    peaks = []
    for i, value in enumerate(data):
        peak = False  # start with the assumed non-peak
        for j in range(max(0, i - 1), max(0, i - span - 1), -1):  # look behind
            peak = value > data[j]  # check if our value is larger than the selected neighbor
            if not peak:  # not a peak, break away
                break
        if peak:  # look behind passed, look ahead:
            for j in range(i + 1, min(i + span + 1, len(data))):
                if value <= data[j]:  # look ahead failed, break away
                    peak = False
                    break
            if peak:  # if look ahead passed...
                peaks.append(i)  # add it to our peaks list
    return peaks

This is the most performant way to do it with look ahead/behind as it breaks away immediately when a condition is not met instead of checking every element with every element.

If you want to count in the neighbors that are of the same value when calculating a peak (so your current peak candidate is the same) you can use peak = value >= data[j] in the look behind and if value < data[j] in the look ahead portions.


问:
Exposing a port other than 3000 with Express and Docker
I'm using Docker to run an Express app and everything is fine if I run it on port 3000. The Dockerfile I'm using for that is

```<code>FROM node:boron

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 3000
CMD ["npm", "start" ]
</code>```

I now wanted to run it on port 3500. I adjusted the Dockerfile to

```<code>FROM node:boron

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 3500
CMD ["PORT=3500", "npm", "start" ]
</code>```

and the docker run command to

docker run -p 3500:3500 me/myapp

It throws the following error

container_linux.go:262: starting container process caused "exec: \"PORT=3500\": executable file not found in $PATH"

I'm sure this is something basic but I'm new to this and couldn't find the solution by googling it. A pointer in the right direction would be very much appreciated.

答:
You're trying to set the environment variable PORT as you would in a bash script. Docker doesn't understand that - the CMD config wants something which it can execute - a command name & some arguments.

The way to do what you want in Docker is to use ENV. In your case, it'd look something like this:

```<code>ENV PORT 3500
CMD ["npm", "start" ]
</code>```

You can put the ENV anywhere in the Dockerfile, before the CMD, but it makes sense to keep a section of them later, so changes don't force a costly rebuild and more layers can be shared.

Body:
I'm using Docker to run an Express app and everything is fine if I run it on port 3000. The Dockerfile I'm using for that is

FROM node:boron

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 3000
CMD ["npm", "start" ]

I now wanted to run it on port 3500. I adjusted the Dockerfile to

FROM node:boron

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 3500
CMD ["PORT=3500", "npm", "start" ]

and the docker run command to

docker run -p 3500:3500 me/myapp

It throws the following error

container_linux.go:262: starting container process caused "exec: \"PORT=3500\": executable file not found in $PATH"

I'm sure this is something basic but I'm new to this and couldn't find the solution by googling it. A pointer in the right direction would be very much appreciated.

Body:
You're trying to set the environment variable PORT as you would in a bash script. Docker doesn't understand that - the CMD config wants something which it can execute - a command name & some arguments.

The way to do what you want in Docker is to use ENV. In your case, it'd look something like this:

ENV PORT 3500
CMD ["npm", "start" ]

You can put the ENV anywhere in the Dockerfile, before the CMD, but it makes sense to keep a section of them later, so changes don't force a costly rebuild and more layers can be shared.


问:
IOS/Objective-C:Add another variable to a mutableArray
I have a simple array of strings such as the following:

```<code>myArray *NSArray = [NSArray arrayWithObjects: @"chevy", @"ford", @"toyota", nil];
</code>```

I want to add another dimension to the array such as @"1",@"2",@"3" in order to keep track of the order.

Is there a simple way to do this?

Edit

I found answer here.  Create 2nd array and employ loop:

```<code>//For your 2D array
NSMutableArray *secondArray = [[NSMutableArray alloc] initWithCapacity:[homePlayersArray count]];

//populate as required
for(int i=0;i<[homePlayersArray count];i++){
    NSArray *tempArray = [[NSArray alloc] initWithObjects:[homePlayersArray objectAtIndex:i],[NSNumber numberWithInt:0], nil];
    [secondArray addObject:tempArray];
}
</code>```

答:
Create NSDictionary instead of NSArray

```<code>NSDictionary *dictionaryOfCars = @{ @"1" : @"chevy", @"2" : @"ford", @"3" : @"toyota"};
</code>```

You can access any item in dictionary using :

```<code>id item = [dictionaryOfCars objectForKey:@"1"];// item  = @"chevy"
</code>```

Body:
I have a simple array of strings such as the following:

myArray *NSArray = [NSArray arrayWithObjects: @"chevy", @"ford", @"toyota", nil];

I want to add another dimension to the array such as @"1",@"2",@"3" in order to keep track of the order.

Is there a simple way to do this?

Edit

I found answer here.  Create 2nd array and employ loop:

//For your 2D array
NSMutableArray *secondArray = [[NSMutableArray alloc] initWithCapacity:[homePlayersArray count]];

//populate as required
for(int i=0;i<[homePlayersArray count];i++){
    NSArray *tempArray = [[NSArray alloc] initWithObjects:[homePlayersArray objectAtIndex:i],[NSNumber numberWithInt:0], nil];
    [secondArray addObject:tempArray];
}

Body:
Create NSDictionary instead of NSArray

NSDictionary *dictionaryOfCars = @{ @"1" : @"chevy", @"2" : @"ford", @"3" : @"toyota"};

You can access any item in dictionary using :

id item = [dictionaryOfCars objectForKey:@"1"];// item  = @"chevy"


问:
How to send the index of a for loop into the promise of a function in a Vue Resource call?
I am looping through an object however in the asynchronous part the i variable is always five.

How can I maintain that value, or pass it into the function

```<code>getProductData: function() {
                var vm = this;
                for (var i = 0; i < vm.recommendationResponse['recommendedItems'].length; i++) {
                    var sku = vm.recommendationResponse['recommendedItems'][i]['items'][0]['id'];
                    vm.$http.get('http://127.0.0.1:8000/models/api/productimage/' + sku).then(response => {
                        // get body data
                        vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = response.body['product_image_url'];
                        vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = response.body['price'];
                    }, response => {
                        vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = '';
                        vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = '';
                    });
                }
            }
</code>```

I I do something like this:

vm.$http.get('http://127.0.0.1:8000/models/api/productimage/' + sku).then((response, i) => ...

then i is undefined

Who do I keep the index of the loop or should I go about it a different way?

答:
Always use let to initialize variables in for loop when dealing with async operations. Similar things goes to having for loops in intervals. By using let you make sure you always have a unique variable assigned to i.

```<code>for (let i = 0, recommendationlength = vm.recommendationResponse['recommendedItems'].length; i < recommendationlength; i++)
</code>```

Little bonus, if you cache array length in the beginning you get a small performance boost :-)

Body:
I am looping through an object however in the asynchronous part the i variable is always five.

How can I maintain that value, or pass it into the function

getProductData: function() {
                var vm = this;
                for (var i = 0; i < vm.recommendationResponse['recommendedItems'].length; i++) {
                    var sku = vm.recommendationResponse['recommendedItems'][i]['items'][0]['id'];
                    vm.$http.get('http://127.0.0.1:8000/models/api/productimage/' + sku).then(response => {
                        // get body data
                        vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = response.body['product_image_url'];
                        vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = response.body['price'];
                    }, response => {
                        vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = '';
                        vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = '';
                    });
                }
            }

I I do something like this:

vm.$http.get('http://127.0.0.1:8000/models/api/productimage/' + sku).then((response, i) => ...

then i is undefined

Who do I keep the index of the loop or should I go about it a different way?

Body:
Always use let to initialize variables in for loop when dealing with async operations. Similar things goes to having for loops in intervals. By using let you make sure you always have a unique variable assigned to i.

for (let i = 0, recommendationlength = vm.recommendationResponse['recommendedItems'].length; i < recommendationlength; i++)

Little bonus, if you cache array length in the beginning you get a small performance boost :-)


问:
How does MbUnit work with VS 2008
I set up MbUnit and have been trying to get it to work with VS 2008 using the MbUnit GUI but every time I run a test it closes and I get a this program needs to close error.

I had a similar problem with Gallio where I got a runner exception every time I ran a test.

Do I need an addin for VS like testDriven.Net to get this to work?

答: I'm using combination of Visual Studio 2008, ReSharper 4.1 and latest builds of Gallio. With that it works pretty well.</p>

OwnerDisplayName: Calum

LastEditorDisplayName: Kent Fredric

Title: How does MbUnit work with VS 2008

OwnerDisplayName: Krzysztof Koźmic


答:
You could use Array.prototype.forEach instead:

```<code>var vm = this;
vm.recommendataionResponse['recommendedItems'].forEach((item, i) => {
  var sku = vm.recommendationResponse['recommendedItems'][i]['items'][0]['id'];
  vm.$http.get('http://127.0.0.1:8000/models/api/productimage/' + sku).then(response => {
    // get body data
    vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = response.body['product_image_url'];
    vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = response.body['price'];
  }, response => {
    vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = '';
    vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = '';
  });
})
</code>```

This way, since there is a unique scope for each i value, each .then callback will be able to reference the correct value.

Title: How to send the index of a for loop into the promise of a function in a Vue Resource call?

Body:
You could use Array.prototype.forEach instead:

var vm = this;
vm.recommendataionResponse['recommendedItems'].forEach((item, i) => {
  var sku = vm.recommendationResponse['recommendedItems'][i]['items'][0]['id'];
  vm.$http.get('http://127.0.0.1:8000/models/api/productimage/' + sku).then(response => {
    // get body data
    vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = response.body['product_image_url'];
    vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = response.body['price'];
  }, response => {
    vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = '';
    vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = '';
  });
})

This way, since there is a unique scope for each i value, each .then callback will be able to reference the correct value.


问:
How to get intellisense for AngularJS in VSCode?
So can anyone help me get the AngularJS intellisense working in Visual Studio Code?

Is it possible to configure this globally or can it only per project? I'm preferably looking for a solution on how to do this globally, as in whenever I open VSCode AngularJS intellisense just works.

I'm currently using AngularJS 1.5.x. I do not know if it possible to configure according to the version of AngularJS being used.  Additionally, I'm using VSCode 1.10.2 and VSCode - Insiders on Windows 10.

I've already searched in several places, but the solutions I've found did not work for me. Maybe it's because they are old.

答:
There are many extensions available for intellisense in Angular (2+), but not for AngularJS.  However, this article by Mike Barlow explains how to do it and it's fairly recent since you've asked your question (June 2016).

Here's the summary of what you need to do per the article:

Have the following tools installed:  node.js 6.2+, npm 3.9+, and VSCode 1.2+.

Install the typings package globally:  npm install -g typings. Make sure this is a 1.X version.

Install AngularJS types:  typings install dt~angular --save --global

This should create a a folder typings\globals\angular\ with a file called "typings.json"

Create a file within this directory as a sibling to "typings.json" called "jsconfig.json".  This file can remain empty unless you need to transpile code (ie, using typescript, coffeescript, etc.)

Restart VSCode


问:
Await all Tasks in the list, and after that update the list base on task result
I want to run all tasks with WhenAll (not one by one).
But after that I need to update list (LastReport property) base on result.

I think I have solution but I would like to check if there is better way.

Idea is to:

Run all tasks

Remember relation between configuration and task

Update configuration

My solution is:

```<code>var lastReportAllTasks = new List<Task<Dictionary<string, string>>>();
var configurationTaskRelation = new Dictionary<int, Task<Dictionary<string, string>>>();
foreach (var configuration in MachineConfigurations)
{
    var task = machineService.GetReports(configuration);
    lastReportAllTasks.Add(task);
    configurationTaskRelation.Add(configuration.Id, task);
}

await Task.WhenAll(lastReportAllTasks);
foreach (var configuration in MachineConfigurations)
{
    var lastReportTask = configurationTaskRelation[configuration.Id];
    configuration.LastReport = await lastReportTask;
}
</code>```

答:
I think you don't need Lists or Dictionaries. Why not simple loop which updates LastReport with results

```<code>foreach (var configuration in MachineConfigurations)
{
    configuration.LastReport = await machineService.GetReports(configuration);
}
</code>```

For executing all reports "in parallel"

```<code>Func<Configuration, Task> loadReport =
    async config => config.LastReport = await machineService.GetReports(config);

await Task.WhenAll(MachineConfigurations.Select(loadReport));
</code>```

And very poor try to be more functional.

```<code>Func<Configuration, Task<Configuration>> getConfigWithReportAsync =
    async config =>
    {
        var report = await machineService.GetReports(config);
        return new Configuration
        {
            Id = config.Id,
            LastReport = report
        };
    }

var configsWithUpdatedReports =
    await Task.WhenAll(MachineConfigurations.Select(getConfigWithReportAsync));
</code>```

Body:
I want to run all tasks with WhenAll (not one by one).
But after that I need to update list (LastReport property) base on result.

I think I have solution but I would like to check if there is better way.

Idea is to:

Run all tasks

Remember relation between configuration and task

Update configuration

My solution is:

var lastReportAllTasks = new List<Task<Dictionary<string, string>>>();
var configurationTaskRelation = new Dictionary<int, Task<Dictionary<string, string>>>();
foreach (var configuration in MachineConfigurations)
{
    var task = machineService.GetReports(configuration);
    lastReportAllTasks.Add(task);
    configurationTaskRelation.Add(configuration.Id, task);
}

await Task.WhenAll(lastReportAllTasks);
foreach (var configuration in MachineConfigurations)
{
    var lastReportTask = configurationTaskRelation[configuration.Id];
    configuration.LastReport = await lastReportTask;
}

Body:
I think you don't need Lists or Dictionaries. Why not simple loop which updates LastReport with results

foreach (var configuration in MachineConfigurations)
{
    configuration.LastReport = await machineService.GetReports(configuration);
}

For executing all reports "in parallel"

Func<Configuration, Task> loadReport =
    async config => config.LastReport = await machineService.GetReports(config);

await Task.WhenAll(MachineConfigurations.Select(loadReport));

And very poor try to be more functional.

Func<Configuration, Task<Configuration>> getConfigWithReportAsync =
    async config =>
    {
        var report = await machineService.GetReports(config);
        return new Configuration
        {
            Id = config.Id,
            LastReport = report
        };
    }

var configsWithUpdatedReports =
    await Task.WhenAll(MachineConfigurations.Select(getConfigWithReportAsync));